JWT Guides

How I Check the JWT exp Claim and Expiration Time

See how I inspect JWT exp, convert NumericDate values, account for clock skew, and decide whether expiration is really causing the failure.

By JWTDecoder.toolsLast verified 2026-09-12

Editorial voice: first-person phrasing describes the documented JWTDecoder.tools workflow; JWTDecoder.tools is the publisher and organizational author.

JWT timeline showing iat, nbf, active time and exp
Check iat, nbf, the active window and exp before blaming expiration.

When I see token expired, jwt expired, or a 401 that might be time-related, the first claim I check is usually exp. I do not assume the library error tells the whole story. I decode the token, convert the timestamp myself, compare it with the verifier's clock, and then decide whether expiration is actually the root cause.

If I only need a fast answer, I use the JWT Expiry Checker to turn exp, iat and nbf into readable UTC times.

What I expect exp to mean

RFC 7519 defines exp as the JWT Expiration Time. It is a NumericDate value measured in seconds from the Unix epoch.

A payload can look like:

{
  "sub": "user_123",
  "iat": 1789200000,
  "exp": 1789203600
}

When I inspect this token, I read iat as the declared issue time and exp as the point after which the token should no longer be accepted.

The comparison I care about is conceptually:

current verifier time >= exp

Once that becomes true, a verifier enforcing expiration should reject the token.

The first mistake I check for: seconds versus milliseconds

This is one of the easiest JWT bugs to spot.

JWT NumericDate values use seconds. JavaScript Date.now() uses milliseconds.

So when I check a token in JavaScript, I expect code like:

const expiresAt = payload.exp * 1000;
const expired = Date.now() >= expiresAt;

If I see code comparing Date.now() directly with a normal ten-digit exp, I know the units are wrong.

I use the decoder or expiry checker to avoid doing this conversion mentally, especially when I am comparing logs from several services.

How I tell whether the token is actually expired

I use a short sequence:

  1. I decode the token and confirm exp exists.
  2. I convert exp to UTC.
  3. I compare it with the clock used by the service that rejected the token.
  4. I inspect nbf and iat at the same time.
  5. I check whether the verifier applies clock tolerance.

The important detail is step 3. My laptop clock is not necessarily the authority. The API or gateway doing the verification uses its own clock.

How I think about clock skew

RFC 7519 allows implementations to use a small amount of leeway to account for clock differences.

When a token appears to expire slightly too early, I check three things before changing configuration:

  • is the API server clock synchronized?
  • is the identity provider clock synchronized?
  • does the JWT library have an explicit tolerance setting?

I do not add a large grace period just to make the error disappear. A wide tolerance effectively extends the acceptance window beyond the issuer's declared exp value.

If the failure is only a few seconds around the boundary, clock skew is plausible. If the token expired an hour ago, skew is not a useful explanation.

What I do when exp is missing

A missing exp does not automatically mean the JWT format is malformed.

The base JWT specification defines exp, but different token profiles decide which claims are required. So I do not label every token without exp as invalid.

Instead, I ask what kind of token I am dealing with and what policy the application expects.

For an access token that is supposed to be short-lived, missing expiration is something I want to investigate. The JWT Validator reports that condition without pretending that every JWT profile has identical requirements.

Why an unexpired token can still fail

This is the point where I avoid tunnel vision.

If exp is still in the future, I move on. A token can be unexpired and still fail because:

  • its signature does not verify;
  • nbf is in the future;
  • the issuer is wrong;
  • the audience is wrong;
  • the token came from another environment;
  • the API expects a different token type;
  • required scopes or roles are missing.

If time looks fine, I use the JWT Debugger for issuer/audience checks and the JWT Signature Verifier when I have trusted key material.

Why I do not edit exp to “fix” the token

If a signed token is expired, I do not change the payload and expect the old signature to remain valid.

The signature covers the encoded header and payload. Changing:

{
  "exp": 1789203600
}

to a later value changes the signed bytes.

Without authorized signing credentials, the modified token should fail signature verification.

The legitimate fix is usually to obtain a new token through the authentication or refresh flow supported by the system.

How I use iat, nbf and exp together

I rarely inspect exp in isolation. I look at the token timeline:

issued -------- active window -------- expired
  iat     nbf                     exp

I ask:

  • does iat make sense for when the login happened?
  • is nbf later than the current verifier time?
  • is exp later than iat?
  • is the declared lifetime unexpectedly long or short?

An odd timeline can reveal a unit conversion error, a clock problem, a bad token from another environment, or a profile-specific policy issue.

My practical exp troubleshooting flow

When I suspect expiration, I work through this order:

  1. I open the JWT Expiry Checker.
  2. I confirm exp is interpreted as seconds, not milliseconds.
  3. I compare the decoded UTC time with the rejecting service's clock.
  4. I inspect iat and nbf for contradictions.
  5. I check configured clock tolerance.
  6. If the token is genuinely expired, I replace it through the intended authentication flow.
  7. If the token is still active, I stop blaming exp and check issuer, audience and signature.

For me, exp is a fast diagnostic signal, not a complete verdict. It answers “is this token outside its declared time window?” It does not answer “should this application trust and accept the token?”

Sources

Related guides