EasyDeveloper

JWT

JWT Expiration Explained: exp, iat, nbf and Refresh Tokens

Published 2026-08-15 · 8 min read

TL;DR: A JWT expires when its exp claim passes, and a verifying server rejects it after that; applications therefore pair a short-lived access token with a longer-lived refresh token.

A JWT stops being valid at the instant named by its exp claim, and the whole expiration model of JWT-based sessions rests on that one number. The exp claim is stored as epoch seconds - seconds since 1970-01-01 UTC - and a verifying server rejects a token once that instant has passed. Shorter lifetimes mean less damage if a token leaks; refresh tokens are how applications keep sessions alive without sacrificing that. The exp claim is defined in RFC 7519.

What does exp mean in a JWT?

exp, short for expiry, is a registered claim that sets the moment after which the token must not be accepted. It is a number of epoch seconds, the same format as a Unix timestamp, which you can convert with any epoch converter. A payload carrying exp 1516242622 means the token is valid until that instant and rejected after it.

{
  "sub": "1234567890",
  "iat": 1516239022,
  "exp": 1516242622,
  "aud": "api.example.com"
}

Here iat marks when the token was issued and exp is exactly one hour later. The window between the two is the token lifetime, and it is a deliberate design decision rather than an accident.

How does the server enforce exp?

A validator compares exp against the current time and rejects the token when the time has passed, typically with a 401 response. Because the two clocks involved - the issuer and the validator - can drift by a few seconds, validators allow a small clock skew, commonly 30 to 60 seconds, before declaring a token expired. Libraries expose this as a clockTolerance or leeway option.

The check happens as part of validating the token: the server verifies the signature first, then checks that exp has not passed and that iss and aud match. An expired token fails the same way whether the signature is valid or not.

What do iat and nbf mean?

iat is issued at, the epoch second when the token was created, and nbf is not before, the earliest instant the token should be accepted. A token with nbf in the future exists but is not yet valid, which is useful when a service is provisioning a token ahead of a known switch-over time. Both claims work like exp in reverse and are checked against the same clock with the same tolerance.

What happens when a JWT expires mid-session?

  • The next request returns 401, and the client no longer has a valid credential.
  • If a refresh token exists, the client exchanges it for a fresh access token and retries.
  • If no refresh token exists, the user is sent through login again.
  • Front-end code that sees 401 should distinguish an expired token from a bad one before logging the user out.

The key detail is that nothing on the server needs to fire at the expiry instant. Expiry is enforced lazily: the next request to present the token fails. There is no timer and no revoke list, which is exactly why short expiries matter - the window of acceptance is bounded by the lifetime you choose.

What is a refresh token?

A refresh token is a second credential with a long lifetime, often days or weeks, that can be exchanged for a new short-lived access token. It is usually opaque - a random string stored server-side - rather than a JWT, precisely because it does not need to carry claims. The pattern keeps access tokens short, so a stolen access token is only useful briefly, while the refresh token is the thing that survives and can be revoked by deleting its server-side record.

Can you extend a JWT?

The signed token itself cannot change - re-signing it with a later exp produces a different token. So extension always means issuing a new token, and the two common approaches are fixed lifetimes with a refresh flow, or sliding expiration, where every successful request issues a fresh token with a renewed exp. Sliding expiration is convenient for long editor sessions but keeps tokens valid as long as the user stays active.

How do you check a JWT expiry?

Decode the payload and read exp, then compare it to the current time. The JWT Decoder decodes the token and highlights the exp claim, and the JWT Validator performs the comparison for you and reports whether the token is expired. When you issue tokens yourself, keep exp short - minutes to hours for access tokens - and lean on refresh tokens for the rest.

Frequently Asked Questions

What happens when a JWT expires?

The token stops being accepted. A verifying server reads exp, compares it to the current time, and returns 401 when the time has passed. The client must get a new token through a refresh flow or a fresh login.

Can you extend a JWT after it expires?

No, not the same token. The token is immutable once signed, and re-signing it with a later exp makes it a new token. Servers extend sessions by issuing a new access token, often in exchange for a refresh token.

Is the exp claim required in a JWT?

Not by the grammar, but it should be in practice. An unsigned exp claim means a token never expires on its own, which is a security problem if the token leaks. Most validators and libraries encourage or enforce exp.

What is a refresh token?

A separate, usually opaque token with a long lifetime that can be traded for a fresh access token. It lets a client keep a user signed in without forcing a login while keeping the access token itself short-lived.

What is clock skew in JWT validation?

Clock skew is the difference between the issuer clock and the validator clock. Because servers can disagree by seconds, validators typically allow a small tolerance, such as 30 seconds, when comparing exp against the current time.