A decoded JWT can look fine while still being expired, not yet valid, signed with the wrong key or meant for a different audience.
Symptoms
- Token decodes correctly but the API rejects it.
- exp appears far in the past or far in the future.
- Only one server rejects the token.
Likely causes
- exp, iat or nbf use milliseconds instead of seconds.
- Server clock skew makes the token appear expired or not yet valid.
- aud, iss or signature verification fails even though payload decoding works.
Fix steps
- Decode claims and convert timestamps to UTC.
- Compare token time against server time.
- Verify signature and expected issuer/audience on the backend.
Verify the fix
- Generate a fresh token and test immediately.
- Check server NTP/time sync.
- Log auth failure reason without exposing token values.
FAQ
Does decoding prove a JWT is valid?
No. Decoding only reveals payload. Signature and claims must be verified.
Are JWT times seconds or milliseconds?
Standard JWT NumericDate values are seconds.
Related tools and guides
Last updated: May 18, 2026