A JWT decoder can reveal a token's contents in seconds, but decoding is only the first step in authentication troubleshooting. This guide explains JWT structure, claim inspection, expiration checks, signature verification, and a safe workflow for diagnosing rejected tokens without treating readable data as trusted data.
Overview
JSON Web Tokens (JWTs) are compact strings commonly used to carry authentication and authorization information between a client and an API. A token may appear in an HTTP Authorization header, a cookie, or another application-specific location. When an API returns an authentication error, inspecting the JWT can help determine whether the problem is an expired token, an unexpected issuer, a wrong audience, a missing scope, or a malformed request.
A typical signed JWT has three dot-separated parts:
header.payload.signatureThe header and payload are JSON objects encoded with Base64URL. The signature is a cryptographic value calculated from the encoded header and payload. Because Base64URL encoding is reversible, anyone who has the token can usually read the header and payload. That readability is not encryption, and it does not prove that the claims are genuine.
This distinction is the central rule for using a JWT decoder: decoding helps you inspect a token; signature verification and claim validation are what allow a service to decide whether to trust it. Do not paste a production token into an unfamiliar online tool. Even if a token is short-lived, it may contain personal data or still be usable. Prefer a local decoder, a trusted development environment, or a redacted test token.
Core framework
1. Read the token structure
Start by confirming that the value has the expected shape. A signed JWT normally contains two periods and three segments. The first segment is the header, the second is the claims payload, and the third is the signature. A token with fewer segments may be truncated, incorrectly copied, or based on a different token format.
The header often includes an alg field identifying the signing algorithm and a typ field such as JWT. Some tokens also include a key identifier such as kid. The header tells a verifier how to interpret the signature; it is not an instruction that an application should accept without restrictions. The server should select permitted algorithms through configuration and policy rather than blindly trusting the token header.
2. Inspect claims without trusting them
The payload contains claims: named values that describe the token and its intended use. Common registered claims include:
iss(issuer): the system that created the token.sub(subject): the identity or entity represented by the token.aud(audience): the service or services for which the token is intended.exp(expiration time): the point after which the token should not be accepted.nbf(not before): the time before which the token should not be accepted.iat(issued at): the time the token was created or issued.jti: a token identifier, when the issuer provides one.
Applications may also use claims such as scope, roles, or provider-specific fields. Claim names and formats are not universal. For example, one service may represent scopes as a space-delimited string while another uses an array. Confirm the expected format in the API or identity provider configuration before assuming that a claim is missing.
3. Check time values correctly
JWT time claims are commonly represented as NumericDate values: a number of seconds relative to the Unix epoch. They are not automatically human-readable dates. Compare them with the server's current time, account for small clock differences where appropriate, and check whether the application expects seconds rather than milliseconds.
An expired token is indicated when the current validation time has passed exp. A token may also be rejected because the current time is earlier than nbf. If a token appears valid in a browser but fails at an API gateway or container, compare the clocks and timezone-independent timestamps on the systems involved. The important value is the epoch timestamp, not the local display format.
4. Verify the signature and validation context
Signature verification requires the correct key and algorithm. For a shared-secret design, the verifier needs the expected secret. For a public-key design, it needs the issuer's matching public key, often selected using the header's kid. A successful decode does not provide either key and does not establish that the token came from the claimed issuer.
After cryptographic verification, the service should validate the claims relevant to its context. That commonly includes the expected issuer, audience, expiration, not-before time, and required permissions. A signature can be valid while the token is still unsuitable for a particular API if its audience is different or its authorization claims do not grant the requested operation.
For troubleshooting, separate these questions:
- Can the token be parsed?
- Is its signature valid with the expected key and algorithm?
- Is it current according to its time claims?
- Was it issued for this service and this identity context?
- Does it contain the permission required by the endpoint?
This sequence prevents a readable payload from being mistaken for an authenticated request. For related API response inspection, a JSON formatter and validator can make nested claims easier to review, but formatting does not change their trust status.
Practical examples
Example: a token is rejected as expired
Suppose a decoded payload contains an exp value that converts to a time in the past. The practical fix is usually to obtain a fresh access token through the application's normal authentication flow. Do not extend the expiration value by editing the payload. Any change to the header or payload invalidates a correctly calculated signature, and a client should not be responsible for rewriting issuer-controlled claims.
Example: a token has the wrong audience
A token can be validly signed and not expired while still receiving a 401 response because its aud claim identifies a different API. Check whether the frontend requested a token for the correct resource or scope. Also check whether an API gateway and the application use the same audience convention. A mismatch here is a configuration problem, not a decoding problem.
Example: a signature cannot be verified
If a verifier reports an invalid signature, compare the complete token, the configured algorithm, and the active signing keys. Copying a token through a log, environment variable, or header can introduce whitespace or truncation. With rotating keys, the verifier may also be using an outdated key set. A kid mismatch can help identify key-selection problems, but it should not be “fixed” by accepting an arbitrary key.
Example: authorization fails after authentication succeeds
An API may accept the token's signature and identity but deny an operation because the required scope or role is absent. Check the endpoint's authorization rule, the claim name it reads, and whether the token was issued before a permission change. This is different from an invalid-token error: authentication establishes who or what presented the token, while authorization determines what that identity may do.
When using a decode JWT token online tool for a non-sensitive test value, treat it as an inspection aid only. For production debugging, use a local command-line or application library and log only selected, non-sensitive metadata such as issuer, audience, key identifier, and expiration status. Never place full access tokens in issue trackers or permanent logs.
Common mistakes
- Confusing Base64URL with encryption. Anyone holding a normal signed JWT may be able to decode its header and payload. Avoid putting secrets or unnecessary sensitive data in claims.
- Assuming decoding verifies authenticity. A decoder can display a forged payload just as easily as a legitimate one. Trust comes from signature verification and claim validation.
- Reading milliseconds as seconds. Time-unit confusion can make a fresh token appear expired or make an expiration check behave unpredictably.
- Checking only
exp. Issuer, audience, not-before, signature, and permission checks can all affect acceptance. - Editing a token to troubleshoot it. Treat edited tokens as test fixtures, not credentials. Changing claims does not create a valid authenticated token.
- Logging complete tokens. Access tokens should be handled like credentials. Redact them and retain only the minimum diagnostic information needed.
- Ignoring token type differences. An ID token is intended to describe an authentication event for a client, while an access token is intended for a resource server. Follow the issuer's documented usage rather than sending either token everywhere.
When to revisit
Revisit this troubleshooting process whenever authentication behavior changes, an identity provider rotates keys, an API changes its audience or scopes, or a service moves between environments. Configuration differences between local, staging, and production commonly explain why the same-looking request behaves differently.
For a repeatable investigation, capture the request path, response status, and a redacted summary of the token: algorithm, key identifier, issuer, audience, subject category, expiration status, and required scope. Then compare those values with the API's validation configuration. Check the clock on the client, gateway, and application, and confirm that each service is using the intended key set.
Finally, update your internal runbook when the authentication provider changes token formats, claim names, signing algorithms, or key-discovery methods. Tools such as a JWT decoder, JSON formatter, or API debugging client are useful parts of a developer toolbox, but they should support—not replace—the server's verification rules. The practical goal is to identify exactly which validation step failed and correct that step without weakening authentication.