Skip to content

JWT expiration and clock skew in production

How exp, nbf, iat, skew windows, retries, and regional clocks affect real JWT validation decisions.

Published on 3 min read

JWT expiration bugs are rarely about misunderstanding exp. Most engineers know it is a Unix timestamp and that expired tokens should fail. The trouble starts around the edges: retry queues, mobile devices with bad clocks, CDN workers in different regions, and services that disagree about how much clock skew is acceptable. A five minute tolerance can be helpful reliability work or a quiet extension of every stolen token.

The claims are simple, the system is not

exp says when the token stops being valid. nbf says when it starts. iat says when it was issued, but many verifiers treat it as informational unless you add policy. In a single process with NTP working, that sounds easy. In a distributed stack, the token might be minted in one region, verified in another, retried by a client after a timeout, then delivered to a worker queue seconds later.

Attackers care about the tolerance window. If access tokens nominally expire after ten minutes and the verifier accepts five minutes of skew, the useful lifetime after theft is closer to fifteen minutes. If refresh endpoints use different skew than APIs, a stolen token may fail in one place but still renew in another.

Choosing a skew window

Use the smallest skew that matches measured clock behavior, not a folklore default. Thirty to sixty seconds is enough for many server side systems with healthy time sync. Mobile and desktop clients can be wrong by minutes, but the server should still be the authority. If a client clock is bad, fix UX around refresh and retry rather than granting every token a broad grace period.

Edge cases to test

Test tokens that expired one second ago, just inside the skew window, and just outside it. Test nbf in the near future. Test iat far in the future, because some systems accidentally accept tokens from tomorrow. Also test background jobs. If a request enqueues work using a token that expires before the worker runs, the worker should use a derived authorization decision or service credential, not re-trust a stale user token.

Logging and incident handling

Log the verifier clock, claim timestamp, skew applied, and failure reason. Without those fields, expiration incidents become guesswork. Avoid logging raw tokens. During suspected token theft, reducing skew can be a practical containment step, but only if you know which services enforce it consistently.

A sane policy

Short lived access tokens, narrow skew, explicit refresh behavior, and consistent verifier code beat clever exceptions. Document the exact interpretation of exp, nbf, and iat per issuer. The policy should be boring enough that an on-call engineer can predict the outcome from three timestamps and a service name.

Related articles

How to decide which claims can be trusted, which must be rechecked, and where JWTs should stop carrying authority.
How to inspect JWT problems safely in logs, support tickets, CLI tools, screenshots, and incident channels without spreading bearer tokens.
Operational guidance for JWT signing keys: generation, storage, KMS use, rotation, access control, audit trails, and emergency response.