2026-06-25 · 6 min read · Rahul Chitturi
- jwt
- auth
- debugging
A JWT can decode cleanly and still fail every protected endpoint. When the signature is valid but the verifier rejects the token, the cause is often a mismatch between the token's audience, issuer, tenant, or expected algorithm.
Before rotating keys or rewriting auth middleware, compare the token your client sends with the exact validation rules your API enforces. Most 401s become obvious once the decoded claims and runtime config sit side by side.
Start with iss and aud
The issuer claim identifies who created the token. The audience claim identifies the API or client the token was meant for. Identity providers may issue several token shapes from the same login flow, so an ID token can look legitimate while still being the wrong token for an API.
- Compare iss with the configured authority or tenant URL
- Compare aud with the API identifier, not the frontend client ID
- Watch for trailing slashes and regional issuer hostnames
- Confirm staging tokens are not reaching production APIs
Check token type and algorithm
Access tokens, ID tokens, and refresh tokens have different jobs. Passing the wrong token type can produce a generic 401 even when the JWT is structurally valid. The header matters too: an RS256 verifier should not silently accept HS256, and production systems must never trust alg=none.
If a library reports signature or key errors, inspect the kid header and compare it with the active JWKS key set before assuming the claim values are wrong.
Diff working and failing claims
When one environment works, decode a synthetic working token and the failing token, then diff only the non-secret claims. This catches tenant drift, old client IDs, wrong scopes, and permission arrays that changed names during a provider migration.
- sub and tenant identifiers point to the expected user realm
- scope or permissions include the API action being called
- azp or client_id matches the trusted application
- exp and nbf are valid for the current clock
A Flashman workflow
Use the JWT decoder for local inspection, format provider JSON errors for readable fields, and diff redacted claim sets from working and failing requests. Flashman keeps this debugging loop in the browser, which helps when tokens contain internal tenant IDs or API identifiers.
Use non-production tokens whenever possible. Decoding helps you understand a token, but production authorization must still verify the signature, issuer, audience, lifetime, and scopes on the server.