About JWT Decoder
A JSON Web Token (JWT, RFC 7519) is three base64url-encoded segments separated by dots: header.payload.signature. The header says how the token is signed (e.g. HS256, RS256), the payload carries the claims (who the user is, when the token expires), and the signature lets the receiver verify integrity. Crucially, the first two segments are only encoded, not encrypted — anyone holding a JWT can read everything inside it.
This decoder splits a token, decodes the header and payload, pretty-prints the claims, and highlights expiration — entirely in your browser. That last part matters more for JWTs than for almost any other data: pasting production access tokens into a site that processes them server-side is handing out live credentials. Here, the token never leaves your machine.
How to use JWT Decoder
- Paste your JWT (header.payload.signature) in the input area.
- The tool decodes and displays header, payload, and claims.
- Check expiration and signature details if shown.
Example
Input
Your input or data here
Output
Result will appear here after running the tool
Anatomy of a token
Take a token like eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiIsImV4cCI6MTcyMDAwMDAwMH0.signature. Decoding the first segment yields {"alg":"HS256","typ":"JWT"} (or a JOSE header with kid — the key ID used to pick the right verification key). The second yields the claims. The third segment is raw signature bytes and is not decodable into anything human-readable; its only job is to be verified with the key.
Standard (registered) claims are compact by design: iss (issuer), sub (subject — usually the user ID), aud (audience), exp (expiration), nbf (not before), iat (issued at), jti (token ID). Everything else — role, email, permissions, tenant — is a custom claim chosen by whoever built the auth system.
Timestamps: the exp/iat trap
JWT time claims are NumericDate values: seconds since the Unix epoch (1970-01-01T00:00:00Z). Two practical traps follow. First, JavaScript's Date.now() returns milliseconds — comparing it directly against exp makes every token look expired for the next ~50,000 years; divide by 1000 first. Second, clocks differ between machines: a token minted by a server one minute ahead of yours can appear 'not yet valid' (nbf) locally. Well-behaved validators allow small clock skew (30–120 s).
This decoder converts exp, iat, and nbf into readable dates and tells you whether the token is currently expired — the single most common thing people paste a JWT to find out.
Decoding is not verification
Anyone can mint a token with any claims — sub: admin, role: superuser — and it will decode beautifully. What separates a real token from a forged one is only the signature check against the issuer's key (shared secret for HS256, public key for RS256/ES256). Never make an authorization decision based on decoded-but-unverified claims; that exact mistake, along with accepting alg:none headers, is behind a long list of real-world auth bypasses (CVE-2015-9235 and friends).
Use this tool to inspect; use the JWT Signature Verifier tool (or your framework's verify function) to trust.
Common errors and how to fix them
"Invalid token" / cannot decode
Cause: The string is not three dot-separated segments — often a truncated copy, a token wrapped in quotes from JSON, or 'Bearer ' still prefixed.
Fix: Strip the Bearer prefix and any quotes; confirm exactly two dots. A JWE (encrypted JWT) has five segments and cannot be read without the key.
Payload decodes to garbage
Cause: The segments are base64url, not standard Base64 — decoding with + / rules corrupts characters, or the token was URL-encoded in transit (%3D artifacts).
Fix: Use this decoder (it handles base64url), and URL-decode the token first if it came from a query string.
Token looks fine but the API returns 401
Cause: Usually exp has passed, aud doesn't match the API, or the signature fails at the server (wrong key/kid).
Fix: Check the decoded exp and aud here first — they explain most 401s without touching the server logs.
exp shows a date in 1970 or far future
Cause: The producer wrote milliseconds into exp (or a string), instead of seconds since epoch.
Fix: Fix the issuer: RFC 7519 NumericDate is seconds. A 13-digit exp is milliseconds and breaks compliant validators.
Tips and best practices
- JWTs are bearer credentials — whoever holds one is the user. Treat pasted tokens like passwords; prefer decoding locally (as here) and revoke tokens you have exposed.
- Keep payloads small: JWTs ride in an HTTP header on every request, and most servers cap headers at 8 KB. Fat permission lists belong in a lookup, not in the token.
- Don't put secrets in claims. Base64url is transparent; anything in the payload is public to every holder of the token.
- kid in the header tells the verifier which key to use — invaluable when debugging rotation issues where old tokens verify and new ones don't (or vice versa).
- A five-segment token is JWE (encrypted), not JWS — no decoder can show its payload without the private key.
Frequently asked questions
- Can anyone read my JWT?
- Yes — header and payload are just base64url-encoded JSON, readable by anyone who has the token. Only integrity is protected (by the signature), not confidentiality. Use JWE if the contents must be secret.
- Does this tool verify the signature?
- No — it decodes and inspects. Verification requires the secret or public key; use the JWT Signature Verifier tool for HS256/384/512 checks, or your auth library server-side.
- Why does my token show as expired?
- exp is seconds since the Unix epoch and is compared against current time. If it genuinely passed, the token needs refreshing. If it looks wildly wrong (year 1970 or 50000+), the issuer wrote milliseconds instead of seconds.
- What is the kid field in the header?
- Key ID — a hint telling the verifier which key (from a JWKS set) signs this token. It enables key rotation: multiple keys stay valid while clients migrate.
- Is it safe to paste a production token here?
- Decoding happens entirely in your browser — the token is never transmitted. Still, standard hygiene applies: expired or test tokens are preferable, and any token exposed anywhere should be treated as compromised and rotated.
- What's the difference between JWS and JWE?
- JWS (three segments) is signed but readable — the common access/ID token format. JWE (five segments) is encrypted — payload unreadable without the key. This tool reads JWS.
Embed this tool
Add JWT Decoder to your own site, blog post, or internal docs — free, no signup. The widget runs entirely in your visitors' browsers, same as it does here.
Related tools
- JWT GeneratorCreate JWT with HS256 and custom payload
- Hash GeneratorMD5, SHA-1, SHA-256, SHA-512 hashes
- Password GeneratorCustom length, numbers, symbols
- Password Strength CheckerEvaluate strength and security suggestions
- HMAC GeneratorGenerate HMAC (SHA-1/256/384/512) from key and message
- JWT Signature VerifierVerify HS256/384/512 JWT signature with shared secret