Document Workflow

Check JWT expiration and not-before timestamps

Review JWT exp, nbf, and iat NumericDate claims as Unix seconds, compare them with a UTC rejection time, and keep signature checks separate.

Written and tested by Published: Reviewed:

How this workflow was checked

Verification started with the guide's “Confirm a request occurred after exp” fixture in Unix Timestamp Converter. The run followed “Capture the server evaluation time” through “Convert NumericDate explicitly as seconds”, compared the produced result to the documented expectation, and checked the distinct limits behind “Interpreting NumericDate as milliseconds” and “Sharing the compact token as evidence”.

The converter placed iat and nbf at 23:00 UTC, exp at midnight, and correctly showed the 00:05 server check as expired even after the documented 60-second skew.

Problem

JWT authentication failures are often summarized as an expiration problem even when the real cause is nbf, issuer, audience, signature, revocation, or server policy. RFC 7519 NumericDate counts seconds from the Unix epoch, while JavaScript APIs commonly use milliseconds, so using the wrong unit can move a claim close to January 1970 or far from the intended boundary. A raw token may also contain personal data and a reusable bearer credential. A sound review converts only the needed numeric claims as seconds, compares them with the server's UTC evaluation time, applies the system's documented clock-skew tolerance, and treats the result as timing evidence rather than proof that the token is authentic or authorized.

Sources and standards

These authoritative references define the formats or security boundaries used in this workflow. Tool-specific verification is documented separately above.

When to use this

  • An API returns an authentication or authorization error and the client reports that its session should still be active.
  • A decoded payload contains exp, nbf, or iat and you need readable UTC boundaries without sharing the raw token.
  • Browser, mobile, gateway, and identity-provider clocks disagree near a token lifetime boundary.
  • A test fixture needs a documented expiration window in Unix seconds rather than JavaScript milliseconds.
  • A support note must separate token timing from signature, issuer, audience, scope, and revocation checks.

Steps

  1. Step 1

    Capture the server evaluation time

    Record the API gateway or authorization server's UTC rejection time, status code, request ID, and relevant policy version. Server evaluation time is more useful than the moment a user noticed the error.

  2. Step 2

    Decode only in an approved local context

    Use JWT Decoder only for a token you are authorized to inspect. If the claims are already available in trusted logs, avoid handling the bearer token at all. Decoding does not verify the signature.

  3. Step 3

    Extract and redact the needed claims

    Keep exp, nbf, iat, iss, aud, and only the non-sensitive context required for diagnosis. Remove the compact token, signature, session cookie, unnecessary subject identifiers, and personal claims from shared notes.

  4. Step 4

    Convert NumericDate explicitly as seconds

    Paste labeled values such as iat=1735686000, nbf=1735686000, and exp=1735689600, then select Seconds. NumericDate may be non-integer, but most issuers emit whole Unix seconds.

  5. Step 5

    Apply the boundary rules

    A request must be evaluated before exp and must not be accepted before nbf, subject to the verifier's documented clock-skew allowance. Compare exact numeric times, not an approximate relative-time label.

  6. Step 6

    Check skew and non-time rejection causes

    Record permitted skew and compare server, client, and issuer clocks. Then independently inspect signature verification, algorithm policy, issuer, audience, token type, scope, revocation, and session state.

  7. Step 7

    Write a redacted conclusion

    State the converted UTC claim boundaries, server evaluation time, applied skew, and whether timing explains the rejection. Include a request ID and policy reference, but never paste the raw production token into a ticket or screenshot.

Example

Confirm a request occurred after exp

Input

iat=1735686000 nbf=1735686000 exp=1735689600
server_evaluated_at=2025-01-01T00:05:00Z
allowed_clock_skew=60 seconds

Output

iat: 2024-12-31T23:00:00.000Z
nbf: 2024-12-31T23:00:00.000Z
exp: 2025-01-01T00:00:00.000Z
server evaluation: 2025-01-01T00:05:00.000Z
The request was 300 seconds after exp and remains outside a 60-second skew allowance. Timing explains expiration, but signature and authorization were not evaluated here.

Common mistakes

Interpreting NumericDate as milliseconds

JWT NumericDate uses seconds. Selecting milliseconds for a 10-digit claim produces a 1970 date and can send the investigation toward the wrong clock or issuer.

Sharing the compact token as evidence

A JWT can be a live bearer credential and can expose personal claims. Share redacted claim names, converted boundaries, request ID, and policy context instead of the raw token.

Checking exp but ignoring nbf

A token can be unexpired yet unusable because the server evaluates it before nbf. Review both boundaries and iat when diagnosing issuance timing.

Treating conversion as signature verification

Readable claims do not prove who issued the token or whether its signature is valid. Verification requires trusted keys and explicit algorithm, issuer, audience, and policy checks.

Applying an assumed clock-skew allowance

Different libraries and deployments use different leeway. Record the actual verifier configuration rather than silently adding a convenient tolerance.

FAQ

Are JWT exp, nbf, and iat values seconds or milliseconds?

They are NumericDate values measured in seconds from the Unix epoch. Fractional seconds are permitted by the definition, although most issuers use integers. Select Seconds unless a non-standard producer is explicitly documented.

Is a token valid exactly at its exp value?

The current time must be before exp for acceptance, subject to the verifier's documented leeway. At or after the expiration boundary, it should be treated as expired under the claim rule.

Why can an unexpired token still be rejected?

Possible causes include nbf, invalid signature, disallowed algorithm, issuer or audience mismatch, wrong token type, missing scope, revocation, session policy, or a server clock outside the expected range.

Does decoding a JWT verify its signature?

No. Base64URL decoding only reveals the encoded header and claims. Authenticity requires cryptographic verification with trusted keys and explicit validation rules.

Can I paste a production JWT into the timestamp converter?

Do not paste the compact token when the numeric claims are enough. Extract authorized values locally, then use only labeled exp, nbf, and iat numbers and redact the shared output.

Should I compare the claim with browser time or server time?

Use the verifier's server UTC time for the acceptance decision. Browser time can explain what the user saw, but a client clock does not determine whether the server accepted the token.