🔐 JWT Decoder
Decode and inspect JSON Web Tokens.
🔒 Your data never leaves your browser
Token Info
Header
Payload
Signature
A JSON Web Token is three Base64url-encoded parts separated by dots: a header, a payload, and a signature. This decoder splits the token, decodes the header and payload, and pretty-prints them as JSON. It also shows the signing algorithm, the token type, and whether the payload’s time claims place the token in the past or future. It does not verify the signature, and it cannot tell you whether a token should be trusted.
How to Use
- Paste a token into the input field. Decoding starts as soon as the field contains something.
- Read the token info row: algorithm, type, expiration status, and the expiry date if one exists.
- Inspect the header and payload panels, which show the decoded JSON.
- Read the signature panel, which shows the raw Base64url segment. Copy anything you need from the panels by selecting it.
If the input is empty the panels hide. If the token is malformed, an error message explains whether the header, payload, or overall format is at fault.
What the Three Parts Contain
- Header — a small JSON object describing how the token was signed. The
algfield names the algorithm (for exampleHS256orRS256) andtypis usuallyJWT. Akidmay identify which key was used. - Payload — the claims. Registered claims include
iss(issuer),sub(subject),aud(audience),exp(expiry),nbf(not before),iat(issued at), andjti(token id). Applications add custom claims such as roles or a user id. - Signature — the cryptographic output. It is binary and Base64url-encoded, so the decoder shows it as a string rather than as JSON.
Base64url is a URL-safe variant of Base64: it uses - and _ instead of + and /, and padding = is commonly omitted. The decoder restores padding before decoding.
Decoding Is Not Verification
This is the most important limitation. Base64url decoding is reversible and needs no key at all, so the header and payload are readable by anyone who has the token — they are not secret and not encrypted. A token can be fabricated with any payload the author chooses, and it will decode here perfectly. The decoder never checks the signature, never validates iss or aud, and never rejects a weak algorithm. A token whose header declares "alg":"none" decodes without complaint, which is precisely why decoded content must never drive an authorization decision. Trust comes only from verifying the signature with the correct secret or public key and validating the expected claims on the server.
Reading exp, nbf, and iat
JWT time claims are NumericDate values: seconds since the Unix epoch in UTC, not milliseconds. exp is the moment the token expires, nbf is the earliest moment it may be used, and iat records when it was issued. The decoder compares exp and nbf to your local clock and labels the token valid, expired, or not yet valid, and it renders the expiry as a readable date. Because the comparison uses your machine’s clock and is purely informational, a device with the wrong time can show a misleading label. A token with no exp claim never expires by this check and is labeled valid — again, that is an absence of evidence, not proof of safety.
Worked Example
Take the canonical example token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
The header decodes to {"alg":"HS256","typ":"JWT"}, so the algorithm shows as HS256 and the type as JWT. The payload decodes to {"sub":"1234567890","name":"John Doe","iat":1516239022}, an issued-at time of 22 January 2018. There is no exp and no nbf, so the status reads valid and the expiry shows no expiration. The signature panel shows the final segment as raw text. Nothing in that output proves the token was signed by anyone in particular.
Had the payload also carried an exp, the label would track that timestamp rather than the token’s content: the same string would read valid until the expiry moment and then flip to expired, with no change to the token itself.
Common Decoding Errors
- “Invalid JWT format: expected 3 parts.” The most frequent error. It means the dot-separated structure is broken — a truncated paste, a token copied with an HTTP
Bearerprefix still attached, surrounding quotes, or a token with only two segments. - “Invalid header: not valid base64 encoding.” The first segment contains characters that are neither Base64url nor the restored padding, which usually points to a partial copy or a token type that is not a JWT.
- “Invalid header: not valid JSON.” The segment decodes from Base64url but the resulting text is not JSON. This can happen if the wrong segment was placed first, or if the token was altered.
- A five-segment value. That is a JWE (encrypted token), not a signed JWT. Its content is ciphertext and cannot be read without the decryption key, so this decoder will reject it.
- Percent-encoded input. If the token arrived through a URL and still contains
%2Eor similar escapes, the dots are hidden and the split never happens. Decode the URL first.
The decoder strips whitespace before parsing, so line breaks from a wrapped copy are safe; almost every other failure comes from extra or missing characters.
Related Tools
Frequently Asked Questions
Does a successful decode mean the token is valid or trustworthy?
No. Decoding only Base64url-decodes the header and payload and parses them as JSON. It does not check the signature, the issuer, the audience, or the algorithm. Anyone can construct a well-formed header and payload without knowing any key, so a green status here says nothing about whether a server should accept the token. Always verify the signature and the claims server-side with the right secret or public key.
How does the decoder determine expiration status?
It compares the numeric exp and nbf claims against your computer's current time, converting them from Unix seconds to a local date. If exp is in the past the token is labeled expired; if nbf is in the future it is labeled not yet valid; otherwise it is labeled valid. That label is display-only and uses your local clock, so clock skew or a missing exp claim can change it without the token being any more or less secure.
Why is the signature displayed as raw text instead of decoded JSON?
The signature is binary data encoded with Base64url, not a JSON document. Decoding it would produce unreadable bytes rather than structured claims, so the tool shows the encoded string exactly as it appears in the token. Only the header and payload are JSON and therefore pretty-printed.
Why does my token fail with a format error?
The decoder expects exactly three dot-separated segments. A token with two segments, four segments, a missing segment, or a stray dot is rejected. Copy the token exactly as issued, without adding line breaks or trimming the signature, and make sure you did not accidentally include surrounding text.
Why might a token that works in my app fail here?
The decoder strips all whitespace before parsing, so line wraps are harmless, but it does not understand HTTP syntax or encoding wrappers. If you pasted the value including a Bearer prefix, surrounding quotes, or a URL-encoded copy, the three-part structure is broken and parsing fails. Paste only the raw token string.
Is it safe to paste a production access token into this page?
Decoding happens locally in the browser, so the string is not sent anywhere by the tool. That said, a JWT is a bearer credential: whoever holds it may be able to act as the user until it expires. Avoid pasting live production tokens into any web page, including this one, unless you are certain of the context, and rotate the token if it is ever exposed.
Reviewed by the HandyTools Hub team · Last updated