Paste a JWT and instantly read its decoded header algorithm, all payload claims, expiry timestamp, and issuer. The decoder works with any JWT regardless of signing algorithm — HS256, RS256, ES256, and others. No keys are required for decoding; only signature verification requires a secret.
JWTs are decoded entirely in your browser using JavaScript — your token is never sent to a server. Expiry times are displayed as human-readable dates so you can immediately see whether a token is still valid without parsing Unix timestamps manually.
A JWT is three Base64url-encoded strings joined by dots: header.payload.signature. Each part serves a specific purpose.
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3IxMjMiLCJuYW1lIjoiQWxpY2UiLCJpYXQiOjE3MTY4MjA4MDAsImV4cCI6MTcxNjgyNDQwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header (red)
Contains the token type (typ) and the signing algorithm (alg). Example: {"alg":"RS256","typ":"JWT"}
Payload (purple)
Contains the claims — the data the token carries. Standard registered claims include sub (subject), iss (issuer), exp (expiry), and iat (issued at). Plus any custom claims your application adds.
Signature (green)
Cryptographic proof that the header and payload have not been tampered with. Computed using the algorithm from the header and a secret or private key. Decoding the signature without the key reveals only its bytes — it cannot be verified without the signing key.
RFC 7519 defines these registered claim names. They are not required, but when present, they must follow the standard semantics:
| Claim | Full Name | Type | Description |
|---|---|---|---|
| iss | Issuer | String | Identifies who issued the token. Usually the auth server URL, e.g. https://auth.example.com |
| sub | Subject | String | Identifies the principal the token is about. Usually a user ID or service account identifier. |
| aud | Audience | String or Array | Identifies the recipients the token is intended for. The consuming service must check that its ID is in the audience. |
| exp | Expiration Time | NumericDate | Unix timestamp (seconds). The token must be rejected after this time. |
| nbf | Not Before | NumericDate | Unix timestamp. The token must not be accepted before this time. Useful for delayed-activation tokens. |
| iat | Issued At | NumericDate | Unix timestamp when the token was issued. Used to measure token age. |
| jti | JWT ID | String | A unique identifier for the token. Used to prevent replay attacks by tracking already-used JTIs. |
The alg field in the JWT header tells the verifier which algorithm was used to sign the token. The three most common are:
HS256
HMAC-SHA256 · Symmetric
Uses a single shared secret for both signing and verification. Both the issuer and verifier must know the same secret. Fast and simple, but the verifier must be trusted with the signing key.
Common use: Internal services, single-application tokens
RS256
RSA-SHA256 · Asymmetric
Uses an RSA private key to sign and a public key to verify. The public key can be distributed openly — verifiers don't need the signing secret. Preferred for public APIs.
Common use: OAuth 2.0, OpenID Connect, multi-tenant APIs
ES256
ECDSA-SHA256 · Asymmetric
Elliptic curve equivalent of RS256. Produces shorter signatures with comparable security. Faster than RSA at equivalent security levels. Increasingly common in modern systems.
Common use: Mobile apps, IoT tokens, performance-sensitive systems
The alg: "none" value disables signature verification entirely. Accept tokens with alg: "none" only in contexts where authenticity is guaranteed by other means — accepting them blindly is a critical security vulnerability.
When your API returns a 401 Unauthorized, the JWT decoder is your first diagnostic tool. Here are the most common causes and how to identify them:
Check: Decode the token and look at exp. Compare it to the current time. If exp is in the past, the token is expired.
Fix: Issue a new token via your refresh token flow. Investigate whether the token lifetime is too short for the use case.
Check: Decode the payload and check the aud claim. It must match the identifier your server expects.
Fix: Request a token with the correct audience parameter. In OAuth, specify the resource parameter or audience claim when requesting the token.
Check: Decode the header and check the alg claim. Verify it matches what your server is configured to accept.
Fix: Ensure the token issuer and your verification configuration agree on the algorithm. If you switched from HS256 to RS256, old tokens will fail.
Check: Decode the payload and check the iss claim. It must match the expected auth server URL.
Fix: Ensure you are using the correct auth server in your application config. This commonly happens in multi-environment setups where a production token is used against a dev server.
Check: Decode the iss and sub claims. Production tokens will have different issuer URLs than staging.
Fix: Use the correct environment's auth flow to obtain a valid token for that environment.
For a complete debugging walkthrough, see the blog posts on JWT decoder checklist for auth bugs and validating JWT signatures without a library.
Yes. JWT decoding (reading the header and payload) does not require the signing key — the payload is only Base64url-encoded, not encrypted. Signature verification requires the key. This tool decodes and displays the payload without a key.
Decoding reads the payload claims by Base64url-decoding the middle segment. Verifying checks the cryptographic signature to confirm the token was issued by the expected authority and has not been tampered with. Decoding alone is not sufficient for security — always verify server-side.
A JWT with alg: 'none' has no signature — the third segment is an empty string. This is a special (and potentially dangerous) case used only in contexts where signature verification is handled by other means.
Best practice is 5–15 minutes for access tokens. Short lifetimes limit the window of exposure if a token is stolen. Use refresh tokens (valid for hours or days) to issue new access tokens without requiring the user to log in again.
JWT timestamps (exp, iat, nbf) are Unix timestamps — seconds since January 1, 1970 UTC. The decoder converts them to local time using your browser's timezone. The underlying value is always UTC.
JWT Decoder Checklist for Authentication Bugs
A quick developer checklist to verify token structure, claims, and expiry during auth issue triage.
What Is a JWT Token? How to Decode It
Understand JWT structure and learn a safe decoding workflow for debugging authentication and authorization flows.
How to Validate JWT Signature Without a Library
Use the Web Crypto API to verify HS256 and RS256 JWT signatures natively in browser and Node.js — no dependencies.
Decode Firebase JWT Tokens — Step by Step
How to decode Firebase ID tokens, inspect claims, debug expiry issues, and understand the token structure.