JWT Debugging Checklist: Fix “Invalid Token” Fast
Quick answer: Most JWT failures come from time claims, wrong keys/algorithms, or issuer/audience mismatches. Decode first to see what the token claims. Then verify with the correct key and enforce your expected constraints. Use /jwt-decoder for quick inspection and repeatable troubleshooting.
Start with the failure mode (what exactly is failing?)
Different errors point to different root causes. Expired means time handling or clock skew. Invalid signature means wrong key, wrong algorithm, or token was modified. Wrong audience or issuer means the token is real, but not valid for this service.
What to capture before changing anything:
- The exact error message and where it comes from (gateway, app, identity provider).
- The environment (prod, staging) and region if applicable.
- A redacted token sample and its decoded header/payload.
- The verification configuration (allowed algorithms, issuer, audience, keys).
Common pitfalls:
- Fixing symptoms (retrying, refreshing) without capturing a reproducible sample.
- Mixing up tokens from different clients or tenants.
- Debugging only in the browser when the failure is on the server.
Verify time-related problems first (exp, nbf, iat, clock skew)
Time failures are common and easy to confirm quickly. JWT time claims are typically Unix seconds in UTC. If your server clock is off, valid tokens will look expired. If you parse seconds as milliseconds, the result will be wildly wrong.
Checks that usually pay off:
- Convert exp/nbf/iat to ISO 8601 and compare to “now” on the server.
- Confirm units and parsing library behavior.
- Consider acceptable clock skew for distributed systems.
- Look for tokens with very short lifetimes or refresh timing issues.
Common pitfalls:
- Using client time to decide token validity for server authorization.
- Deploying in containers/VMs without reliable time sync.
- Storing exp as milliseconds in a custom claim and forgetting to convert.
Verify signature and algorithm assumptions (HS vs RS)
Signature errors usually mean wrong key material. HS uses a shared secret; RS/ES use a public key for verification. You cannot verify RS256 with an HMAC secret.
Fast checks:
- Compare header alg to your server allowlist.
- If kid exists, confirm your key set contains that kid.
- Confirm the key format (PEM vs JWK) and any required conversions.
- Check key rotation timing and caching behavior (stale keys are common).
Common pitfalls:
- Allowing algorithm confusion by trusting the token header alone.
- Copying keys with hidden whitespace or wrong line endings.
- Verifying against the wrong tenant or issuer key set.
Verify issuer, audience, and claim constraints
Many “invalid token” incidents are actually “token is valid, but not for you”. iss must match your expected issuer. aud must include your API or client identifier. Your app may also require scopes, roles, or a specific subject format.
Checklist:
- Confirm iss and aud match your environment configuration.
- Verify required scopes/roles are present (and not nested in another claim).
- Confirm token type and client id if your IdP issues multiple kinds of tokens.
- Make sure you are not using an access token where an ID token is expected.
Common pitfalls:
- Mixing staging issuer with production audience (or vice versa).
- Multiple audiences and choosing the wrong one.
- Custom claims moved during an IdP update without downstream updates.
Production safety checklist (avoid risky “fixes”)
Some “quick fixes” create security incidents. Do not disable verification to “make it work”. Do not accept any algorithm unless you intentionally support it. Do not log full tokens in production (they are credentials).
Safer practices:
- Log only non-sensitive identifiers (iss, aud, kid) and a token fingerprint if needed.
- Keep an allowlist of algorithms and rotate keys with clear versioning.
- Validate both signature and claims (issuer, audience, expiry, not-before).
- Treat debugging tokens as secrets and store them securely.
Key takeaways
- Definition: Production safety checklist (avoid risky “fixes”) clarifies what the input represents and what the output should mean.
- Why it matters: correct interpretation prevents downstream bugs and incorrect conclusions.
- Validation: confirm assumptions before changing formats, units, or encodings.
- Repeatability: use the same steps each time so results are consistent across environments.
Common pitfalls
- Mistake: skipping validation and trusting the first output you see in Production safety checklist (avoid risky “fixes”).
- Mistake: mixing formats or layers (for example, decoding the wrong field or using the wrong unit).
- Mistake: losing the original input, making it impossible to reproduce the issue.
Quick checklist
- Identify the exact input format and whether it is nested or transformed multiple times.
- Apply the minimal transformation needed to make it readable.
- Validate the result (structure, encoding, expected markers) before acting on it.
- Stop as soon as the result is clear; avoid over-decoding or over-normalizing.
FAQ
Why does the token work in staging but not production?
Most often the issuer, audience, or key set differs. Compare configuration and key rotation status between environments.
How do I tell if this is a JWT or an encrypted JWE?
A JWE typically has five dot-separated parts. If you cannot parse JSON after decoding, it may not be a plain signed JWT.
Should I ever decode a token on the client?
Decoding for display/debugging is fine. Authorization decisions still belong on the server with verification.
What should I do if the output still looks encoded?
Decode step-by-step. If you still see obvious markers, the data is likely nested or transformed multiple times.
What is the safest way to avoid bugs?
Keep the original input, change one thing at a time, and validate after each step so the fix is reproducible.
Should I use the decoded value in production requests?
Usually no. Decode for inspection and debugging, but send the original encoded form unless the protocol expects decoded text.
Why does it work in one environment but not another?
Different environments often have different settings (time zones, keys, encoders, parsing rules). Compare a known-good sample side-by-side.
References
- RFC 7519: JSON Web Token (JWT) - JWT core spec.
- RFC 7515: JSON Web Signature (JWS) - Signing format.
- RFC 7516: JSON Web Encryption (JWE) - Encrypted tokens.
- RFC 7517: JSON Web Key (JWK) - Key format.
- RFC 7518: JSON Web Algorithms (JWA) - Algorithm definitions.
- RFC 8725: JWT Best Current Practices - Security guidance.
- RFC 8414: OAuth 2.0 Authorization Server Metadata - Issuer metadata.
- RFC 6750: OAuth 2.0 Bearer Token Usage - Bearer token usage.
- IANA JWT Registry - Registered parameters.
- OpenID Connect Core 1.0 - ID token usage.
Key takeaways
- Definition: References clarifies what the input represents and what the output should mean.
- Why it matters: correct interpretation prevents downstream bugs and incorrect conclusions.
- Validation: confirm assumptions before changing formats, units, or encodings.
- Repeatability: use the same steps each time so results are consistent across environments.
Common pitfalls
- Mistake: skipping validation and trusting the first output you see in References.
- Mistake: mixing formats or layers (for example, decoding the wrong field or using the wrong unit).
- Mistake: losing the original input, making it impossible to reproduce the issue.
Quick checklist
- Identify the exact input format and whether it is nested or transformed multiple times.
- Apply the minimal transformation needed to make it readable.
- Validate the result (structure, encoding, expected markers) before acting on it.
- Stop as soon as the result is clear; avoid over-decoding or over-normalizing.