Paste a JSON Web Token and see everything inside it: header, claims with their dates converted to plain language, a live countdown to expiry, and a security review that flags alg "none", signature-length mismatches and tokens that never expire. Then do the step most decoders skip — actually verify the signature, with an HMAC secret or the issuer's public key (PEM, JWK or JWKS), entirely in your browser via Web Crypto. Decoded is not the same as trusted, and this tool never pretends otherwise: the verification state is always on screen.
Decoded ≠ trusted. Decoding only *reads* a token — anyone can read any JWT. A token earns trust only when its signature verifies, below, against the issuer's key.
Nothing leaves this tab. Decoding and verification run in your browser via Web Crypto. No token, secret or key is transmitted or stored — open DevTools → Network and check while you work.
Most decoders stop at reading the token. This one verifies it: HS256/384/512 against a shared secret (entered as plain text, Base64 or Base64URL — the format mix-up is the #1 cause of false failures), and RS256/384/512, PS256/384/512 and ES256/384/512 against the issuer's public key, pasted as a PEM, a single JWK or a whole JWKS set, with the right key picked by the token's kid header. All of it runs through the Web Crypto API in this tab; no key you paste is transmitted anywhere. And the state is never fudged: unverified says unverified, failed says failed, and a verified-but-expired token is called out as both.
When a token will not decode, "invalid token" is not a diagnosis. This decoder validates every segment against the Base64URL rules and reports the first broken one with the segment name, the character position and the rule: the stray "!" at character 13 of the payload, the '=' padding stranded in the middle, the segment whose length is 1 mod 4 and therefore mathematically impossible — the signature symptom of a truncated copy-paste. A caret diagram shows you the spot. This is the feature you will use most, because malformed pastes are what debugging actually consists of.
exp, iat and nbf are shown as real dates in your local time and in UTC, with a live relative phrase and a ticking countdown to expiry. Every registered claim — iss, sub, aud, exp, nbf, iat, jti, auth_time — carries a plain-language explanation of what it means and what your server should check it against. The timing panel also shows your own device's clock next to the token's, because a surprising share of "this token is broken" reports are really "this laptop's clock is wrong", and the page says so when the token's iat sits in your future.
Beyond decoding, the tool audits what it found: alg "none" flagged as critical; an empty signature wearing a signed header; a signature whose byte length does not match its algorithm (truncated, or the header lies about how it was signed); the HS↔RS confusion risk explained when a token from a public provider turns out to be HMAC; tokens with no expiry, and tokens whose lifetime runs to months. These are the checks a senior engineer runs by eye — automated, and written in language a junior can act on.
Load the token into the editor, change a claim, and re-encode it to watch the signature break — the most convincing demonstration there is of what signing does. HS tokens can be re-signed with a secret; asymmetric tokens re-encode unsigned, with the reason stated (private keys never belong in a web page). The compare view diffs two tokens claim by claim — added, removed, changed — which turns "what did the refresh actually change?" from a squinting exercise into a table. A JSON audit report of the whole inspection downloads in one click.
Five one-click samples cover the situations that matter: a valid HS256 token you can genuinely verify with the demo secret printed beside it (then deliberately fail with a wrong one); a valid RS256 token whose public key is supplied, like a real JWKS; an expired token whose signature still verifies, proving the two checks are independent; a token with alg "none"; and a deliberately malformed token whose error message demonstrates the positioned diagnostics. Nothing here is a screenshot of a feature — every sample exercises the real code path.
A JSON Web Token (RFC 7519) is three Base64URL-encoded chunks joined by dots: a header naming the signing algorithm, a payload of claims — statements like "this is user 123, the token expires at 14:00" — and a signature computed over the first two chunks. The misunderstanding is baked into the format's friendly appearance: Base64URL is an encoding, not encryption. Anyone holding a token can read every claim in it, exactly as this page does, without any key. The signature provides integrity — proof the claims were not altered after the issuer signed them — and nothing else. Two rules follow, and most JWT incidents trace back to breaking one of them: never put a secret in a payload, because the world can read it; and never act on a claim from a token whose signature you have not verified, because the world can write it. A decoder, this one included, performs reading only. Reading is always allowed. Trusting is the step that requires cryptography.
Plenty of tools print a green tick for a token they merely managed to parse. Here, verification is a separate, explicit act with three honest outcomes: not attempted (the default — an amber "unverified" state), verified, and failed, plus a fourth, error, when the check itself could not run (an unimportable key, a private key pasted by mistake — which the tool refuses, loudly). Verification means recomputing or checking the signature over the exact bytes of header.payload with the issuer's key, using the Web Crypto API. Symmetric HS algorithms need the shared secret; the asymmetric families — RSASSA (RS), RSA-PSS (PS) and ECDSA (ES) — need only the public key, which is why they dominate public identity providers: the key that verifies can be published for the world, in a JWKS document, while the signing key never leaves the issuer. This tool accepts that public key as an SPKI PEM, as a PKCS#1 PEM (wrapped into SPKI form in your browser, because Web Crypto will not import PKCS#1 directly), as a single JWK, or as a full JWKS set with the key selected by the header's kid. If your flow needs the raw encoded form instead, the companion Base64 encoder & decoder goes the other direction.
The seven registered claims are the token's contract, and each one corresponds to a check your server owes. iss must match a trusted issuer exactly — accepting tokens from any issuer that shares a signing key is a classic federation bug. aud must contain your service's identifier, or a token minted for a different API (with the same keys) becomes a skeleton key. exp and nbf bound the validity window; iat tells you when it was minted and, compared against exp, how long it lives — minutes is healthy for an access token, months is a finding. sub is only meaningful together with iss; neither alone identifies a user. And jti exists so a specific token can be recognised and refused on replay. When a login fails in production, the cause is almost always visible in this table: the token is expired (or your server clock is), the audience names a different environment, the roles claim your code expects was renamed by the issuer. Debugging auth without looking inside the token is guessing; the claims are the ground truth of what the issuer actually sent, which is frequently not what anyone remembers configuring.
Four JWT attacks recur often enough to have earned names, and this page's security review is built around them. alg confusion: a token signed RS256 is re-presented as HS256, and a naive server verifies it with the RSA public key as the HMAC secret — the public key is public, so anyone can forge; the defence is pinning the expected algorithm server-side, never taking it from the token. alg none: the signature is stripped and the algorithm set to "none"; old libraries accepted, modern ones refuse, and the review flags any such token as critical. kid injection: the key-ID header is used to build a file path or SQL query on the server, smuggling traversal or injection through a field developers treat as a label; the review surfaces the kid so you can see exactly what your server would be trusting. And the unglamorous one, the immortal token: no exp, or a lifetime of months, so a single leak is a permanent credential. None of these are visible in the claims table alone — they live in the relationship between header, signature and time, which is why the review panel exists alongside the decoder rather than instead of it. Teams issuing their own tokens can pair this inspection with the password generator for the shared secrets HS signing depends on, and the 2FA authenticator for the second factor that limits what a stolen token can do.
Production tokens rarely arrive broken; they arrive damaged — wrapped across lines in a log viewer, truncated by a terminal, trailing a "Bearer " prefix, missing their final characters to a chat window's width. The symptoms mislead: a JSON parse error in the payload usually means the bytes shifted long before JSON was involved. That is why this decoder validates the encoding layer first and reports it precisely — which segment, which character, which rule — before JSON is even attempted. A Base64URL segment whose length is 1 mod 4 cannot exist; a "+" or "/" in a segment means standard Base64 was used where Base64URL was required; an "=" in the middle means two fragments were spliced. Each has a different fix, and the fix is obvious the moment the error stops being generic. The decoder also tolerates the benign damage (whitespace, the Bearer prefix, trailing padding) and tells you when it has — silent repairs and silent failures are both enemies of debugging. For the JSON itself once it decodes, the JSON formatter is the right next step.
Three refusals are part of the security model. It never accepts a private key: asymmetric verification needs only the public half, and a page that invited private keys would be training exactly the habit attackers pray for — paste attempts are refused with an explanation, not processed. It does not fetch anything: not the JWKS from the issuer (your token's issuer is your business; the page shows you the well-known URL and lets you fetch it yourself), not analytics with token content, nothing. The whole inspection happens in this tab's memory, which you can confirm in your browser's Network panel — a claim about privacy you are invited to test rather than believe. And it does not pronounce tokens "valid": a token whose signature verifies, that is unexpired and well-formed, may still be revoked, issued for another audience, or presented by the wrong party. Validity is a server's decision, made with live context. What a decoder owes you is the complete, accurate contents of the token and the true state of every check that can be run locally — no more, and no less.
Handy utilities in Developer Tools
Encode text or files to Base64 and decode it back to text, images, or files — free, instant, and 100% private in your browser. URL-safe + JWT inspector.
Format, validate & beautify JSON free online. Tree view, exact error locations, JSONPath, sort keys & minify — 100% private, in your browser.
Free password generator with exact entropy maths: strong random passwords, EFF passphrases and pronounceable mode. 100% client-side — nothing leaves your browser.