A JWT decoder can quickly reveal why a token is being rejected, but decoding is only inspection—not proof that a token is authentic. This guide explains how to read JWT headers and claims, check time and audience fields, distinguish decoding from signature verification, troubleshoot common errors, and handle tokens safely during development.
Overview
JSON Web Tokens (JWTs) are compact strings commonly used to carry authentication and authorization information between a client and an API. A token usually has three dot-separated parts:
header.payload.signature
- Header: describes the token type and signing algorithm, such as
typandalg. - Payload: contains claims, which are statements about the subject, issuer, permissions, or token lifetime.
- Signature: helps a verifier determine whether the signed content was altered and whether it was produced with the expected key.
A JWT decoder or JWT debugger can Base64URL-decode the first two parts into readable JSON. That is useful when an API returns an “invalid token” response or when a frontend and backend disagree about expiration, audience, or issuer. However, the decoded payload should not be treated as trusted data. JWT payloads are typically encoded, not encrypted, so anyone who obtains a token may be able to read its claims.
For related work, a JSON formatter and validator can make decoded claims easier to inspect, especially when comparing tokens from different environments.
Core framework
Decode first, verify separately
The most important distinction is between decoding and verification. Decoding converts the header and payload from Base64URL into text. It does not check the signature, confirm the issuer, or establish that the token should be accepted by your application.
Verification is an application or library operation. It normally checks the signature against a trusted secret or public key and validates rules such as the expected algorithm, issuer, audience, and time window. A token can decode perfectly and still be invalid because its signature is wrong, its key is unknown, or one of its claims does not match the API’s configuration.
Read the header carefully
The header often includes:
alg: the signing algorithm expected by the token.typ: commonly a value indicating that the object is a JWT.kid: an optional key identifier used to select a verification key during key rotation.
The alg value is not a command to accept an algorithm without restriction. Verification code should use an explicit allowlist appropriate to the application. Unexpected algorithm values, missing key identifiers, and changes between development and production configuration deserve investigation rather than being bypassed.
Understand the most useful claims
Claims are ordinary JSON fields, but some names have widely understood purposes:
iss(issuer): identifies the system that issued the token.sub(subject): identifies the user, service, or other principal.aud(audience): identifies the intended recipient or API.exp(expiration time): indicates when the token should stop being accepted.nbf(not before): indicates the earliest time at which the token should be accepted.iat(issued at): records when the token was created.jti(JWT ID): provides an identifier that can support tracking or revocation designs.
Time claims are generally represented as numeric date values rather than formatted date strings. A JWT expiration check should therefore account for the expected unit and for modest clock differences between systems. An apparently valid token may fail if the server clock is incorrect, the token is already expired, or a configured tolerance is too strict.
Use a safe inspection workflow
- Obtain a token created specifically for local or test debugging whenever possible.
- Confirm that it does not contain production credentials, sensitive personal data, or a long-lived session.
- Split the token into three parts and decode only the header and payload.
- Format the resulting JSON so names, types, and nested values are easy to compare.
- Check
exp,nbf,iss, andaudagainst the API’s expected configuration. - Verify the signature in the service or a controlled local environment using the correct key and algorithm.
- Remove the token from terminal history, screenshots, issue trackers, chat messages, and temporary files.
When using a decode JWT token online tool, treat the input as potentially exposed unless you have confirmed how the tool processes and stores data. Client-side processing may reduce transmission risk, but it does not make a production token appropriate for pasting into a browser tool. A generated test token is the safer choice.
Practical examples
Example: a token that decodes but fails an expiration check
Suppose a payload contains:
{
"sub": "user-123",
"aud": "payments-api",
"iss": "https://identity.example.test",
"iat": 1760000000,
"exp": 1760003600
}
A decoder can show these values, but it cannot decide whether the API should accept them. The API must determine whether the current time is before exp, whether the audience is exactly the expected value, whether the issuer is trusted, and whether the signature matches the configured key. If the token is sent to an orders API while its audience is payments-api, the audience mismatch may be intentional protection rather than a formatting problem.
Example: troubleshooting an “invalid signature” response
Start by comparing the environment that issued the token with the environment that verifies it. Common causes include:
- The issuer signed with a different secret or key pair.
- A rotated key is identified by a
kidthat the verifier does not recognize. - The verifier expects a different algorithm.
- The token was copied with an extra space, line break, or missing character.
- Base64URL handling or token transport code altered the string.
Compare the raw token at the point of issuance with the raw token received by the API. Do not “fix” the problem by disabling signature validation or accepting any algorithm. Inspect the configuration and key-selection path instead.
Example: checking a frontend request
In browser-based applications, inspect the request headers and confirm that the access token is sent in the format expected by the API, often an Authorization header with a bearer scheme. Check that the application is not accidentally sending an old token from storage, attaching a token to the wrong host, or treating a refresh token as an access token. A JWT decoder can clarify which token is present; it cannot correct an incorrect client-side authentication flow.
For a broader collection of inspection utilities, see the practical developer tools guide covering JSON, regex, JWT, URL, and encoding utilities.
Common mistakes
Assuming encoding means encryption
Base64URL makes bytes transport-friendly; it does not hide the payload. Avoid placing passwords, private keys, API secrets, or unnecessary sensitive information in claims. If confidentiality is required, use an approach designed for encryption and protect the key-management process separately.
Trusting claims before verification
Do not use a decoded sub, role, or permission claim to authorize an action before the token has passed signature and policy validation. A decoded claim is an observation about the input, not evidence that the input came from a trusted issuer.
Checking only expiration
An unexpired token may still be intended for another service, issued by an unexpected authority, or outside its valid start time. Verification should cover the claims relevant to the application, including issuer and audience, rather than treating exp as the sole security check.
Pasting live tokens into public tools
Tokens can provide access even when they look like harmless debugging strings. Prefer local tooling, redacted examples, or short-lived test credentials. If a live token may have been exposed, follow the application’s incident process: revoke or rotate it where supported, review access, and remove copies from logs and collaboration systems.
Ignoring clock and transport problems
Authentication failures are not always cryptographic. Check server time synchronization, proxy behavior, header size limits, newline insertion, URL encoding, and whether a framework has modified the authorization header. Capture diagnostics without logging the complete secret-bearing token.
When to revisit
Revisit this debugging process whenever the identity provider, signing algorithm, key set, API audience, token lifetime, or authentication library changes. It is also worth reviewing after a deployment, key rotation, domain or environment change, or a migration from one identity service to another. Keep a small, non-sensitive test fixture that covers an expired token, a wrong audience, an unknown key identifier, and an invalid signature. These cases make regressions easier to identify without using real user credentials.
As a practical checklist, document which service issues tokens, which services verify them, where public keys or secrets are configured, which claims are required, and how clock tolerance is handled. Then test the complete request path in a controlled environment. Pair JWT inspection with your normal deployment and infrastructure checks; the web deployment checklist can help place authentication testing alongside release, HTTPS, and operational verification.
The right mental model is simple: use a JWT decoder to understand a token, use a verifier to establish authenticity, and use application policy to decide whether the authenticated request is allowed. Keeping those three steps separate makes debugging clearer and prevents a convenient developer tool from becoming a security shortcut.