2026-07-19 · 6 min read · Rahul Chitturi
- jwt
- auth
- debugging
A token can have a valid signature and still fail because time claims are interpreted differently. The exp claim says when the token expires, nbf says when it becomes valid, and iat records when it was issued. Small clock drift can turn those checks into intermittent 401s.
These bugs are frustrating because they depend on which server handled the request, when a queue delivered a job, or whether a client retried after refreshing credentials.
Normalize every timestamp first
JWT time claims are NumericDate values in seconds. Many application logs use milliseconds, ISO strings, or local time. Convert everything to one representation before adjusting verifier settings.
- Decode only safe tokens or synthetic fixtures while investigating
- Convert exp, nbf, iat, server time, and request logs together
- Check whether leeway is applied symmetrically or only to expiration
- Verify NTP health across issuers, API servers, workers, and edge nodes
Separate timing from trust
Do not loosen signature or audience checks while chasing a clock issue. Keep verification strict, then tune time leeway based on measured skew and retry behavior.
If a deploy changed token lifetime, refresh timing, or cache duration, diff the configuration alongside the decoded claims. The failing request may be using an old token with new server expectations.
A Flashman workflow
Use the JWT decoder to inspect safe claim examples, the timestamp converter to align logs, and the diff tool to compare verifier configuration before and after the incident.
A good fix states the exact boundary: issuer clock, verifier clock, seconds-vs-milliseconds conversion, refresh race, or an overly narrow leeway window.