A JWT decoder is useful for troubleshooting API authentication, but decoding is not the same as verifying. This guide provides a reusable checklist for inspecting a token’s header and payload, understanding claims such as exp, iss, aud, and sub, and finding common frontend and backend configuration problems without exposing sensitive credentials.
Overview
A JSON Web Token, or JWT, commonly contains three dot-separated parts: a header, a payload, and a signature. The first two parts are JSON data encoded with base64url. A JWT decoder can read those parts and display their contents, which makes it useful when an API request unexpectedly returns an authentication or authorization error.
Decoding only answers, “What data is present in this token?” It does not answer, “Is this token authentic?” Anyone who has a token can decode its header and payload. Signature verification requires the appropriate algorithm, signing key, issuer configuration, and validation rules. Treat decoded data as diagnostic information, not proof that a token is trusted.
For local debugging, inspect a token alongside the request that uses it. Compare its claims with the API’s expected issuer, audience, scopes, and lifetime. If the token contains personal data, internal identifiers, or production credentials, use a local decoder or a trusted development environment rather than pasting the full value into an online tool. Redact the signature and sensitive claim values when asking for help.
If you are tracing a larger API workflow, the JavaScript and TypeScript API workflow guide can help you combine formatting, validation, decoding, and testing steps. A JSON formatter and validator is also useful after you decode a payload or inspect an API error response.
Checklist by scenario
When a request returns 401 Unauthorized
- Confirm that the request includes the expected
Authorization: Bearer <token>format. - Check that the token has exactly three dot-separated segments. A missing segment often indicates a copied, truncated, or incorrectly transformed value.
- Decode the payload and inspect
exp,nbf,iss, andaud. - Compare the token’s issuer and audience with the API configuration, not just with the frontend environment variables.
- Check whether the client is sending an old token after login, logout, refresh, or account switching.
When a token appears expired
- Read
expas a Unix timestamp in seconds unless the issuing system documents another format. - Compare the expiration time with the current time on the relevant server, not only the developer’s local clock.
- Inspect
iatandnbfwhen present. A token can be rejected because it is not yet valid even when its expiration is in the future. - Check for clock drift between the identity provider, API server, container, and local machine.
- Verify that a refresh flow replaces the access token actually used by the next request.
When the API rejects a seemingly valid token
- Inspect
issfor the exact issuer value, including differences in hostnames, paths, or trailing slashes. - Inspect
audand confirm that the API expects the same audience type and value. Some systems represent an audience as a string; others use an array. - Check
subto determine which user or service identity the token represents. - Look for scope or role claims required by the endpoint, while remembering that claim names vary by identity provider.
- Confirm that the API validates the signing algorithm and key associated with the token’s
algandkidvalues.
When debugging a React or TypeScript client
- Inspect the network request in browser developer tools and compare the sent token with the token stored by the application.
- Check interceptors, fetch wrappers, and server-side rendering boundaries for stale or missing authentication state.
- Ensure that a decoded payload is used only for display or client-side flow hints. Do not use it as the authority for access control.
- Check whether a failed refresh causes repeated requests with the expired token.
For component-level symptoms that accompany authentication bugs, use the React DevTools guide to inspect state and props. The React debugging workflow provides a broader process for isolating frontend failures.
What to double-check
Header versus payload: The header describes the token, commonly including alg, typ, and sometimes kid. The payload contains claims. Neither section should be treated as confidential merely because it is encoded.
Base64url versus ordinary Base64: JWT segments use base64url encoding. Padding may be omitted, and URL-safe characters differ from ordinary Base64. A decoder that does not support base64url can produce confusing output or fail on otherwise valid tokens.
Time units: JavaScript timestamps are commonly represented in milliseconds, while JWT registered time claims are generally expressed in seconds. Multiplying or dividing at the wrong point can make a valid token look expired by a large margin. In JavaScript, compare carefully, for example by converting Date.now() to seconds when appropriate.
Verification context: A successful decode does not validate the signature, issuer, audience, expiration, or permissions. Backend middleware must perform those checks according to the identity provider and API contract.
Token boundaries: Never log complete access or refresh tokens in production. Remove authorization headers from copied request examples, redact user identifiers where necessary, and prefer short-lived test credentials in development.
Common mistakes
- Confusing decoding with authentication. A payload saying
role: adminis not evidence that the request is authorized. The server must verify the signature and enforce permissions. - Reading expiration as milliseconds. This is a frequent source of incorrect JWT expiration debugging in JavaScript applications.
- Checking only
exp. A token can be within its lifetime but still fail because ofiss,aud,nbf, signing-key, scope, or tenant mismatches. - Debugging the stored token instead of the sent token. Interceptors, refresh logic, browser tabs, and server-side rendering can change which value reaches the API.
- Pasting production tokens into third-party tools. Use local inspection for sensitive values and treat any exposed credential as potentially compromised according to your incident process.
- Assuming every claim has the same meaning everywhere. Standard registered claims have common conventions, but custom claims and authorization rules are defined by the issuing and consuming systems.
When to revisit
Return to this checklist whenever an identity provider, API gateway, authentication library, token lifetime, or frontend request layer changes. It is especially useful before a seasonal release or planning cycle, when teams often consolidate environments, rotate keys, change audiences, or revise refresh behavior.
Recheck the workflow after moving between local, staging, and production environments; changing domains or tenants; introducing server-side rendering; or upgrading a JWT library. Also revisit it when a previously reliable request begins failing intermittently, since clock differences, cached tokens, and refresh races may appear only under particular deployment conditions.
For a practical final pass, record the failing request status, inspect the exact sent token safely, decode its header and payload locally, verify time claims and issuer/audience values, then review server-side signature and authorization logs. Do not stop at a readable payload. If the problem is broader than authentication, continue with the React debugging tools workflow and keep sensitive token material out of tickets, screenshots, and shared online tools.