Developer 🔒 Runs in your browser — no data sent to servers

JWT Debugger

A 401 with a token that looks fine is almost always one of six things. This page shows you the token the way the server reads it, so you can find out which.

JWT Token
Secret or public key
The key is used in your browser and is never sent anywhere.
Decoded
Header

          
        
Payload

        
Signature

Sign a token of your own to test an endpoint. Everything is computed in this page.

Signing key

The key and the finished token stay in your browser; neither is sent anywhere, and neither is carried in a share link.

Debug a JSON Web Token That Is Being Rejected

Tokens fail in a small number of ways, and none of them are visible in the token itself — it is three chunks of Base64URL with dots between them. Paste it here and it becomes something you can argue with: every header field and every claim, in a table that says what each one is for, with the expiry translated into plain words and the signature checked against whatever key you have.

It decodes as you type, and nothing is sent anywhere. That is worth stating plainly on a page like this, because the thing you are about to paste is a working credential for somebody's account.

The six failures, in the order worth checking

What went wrongHow it looks hereFix
ExpiredThe line above the header reads "Expired…"Refresh the token; check the clocks if it is only seconds out
Wrong audienceaud names a different APIRequest the token for the audience the API expects
Wrong issueriss is the staging URL, not productionPoint the client at the right issuer, or the API at the right one
Wrong keyVerify says the signature does not matchUse the key the issuer signed with; watch for Base64 secrets
Wrong algorithmThe header says ES256, your key is an RSA keyMatch the key to the algorithm shown beside the key box
Not a JWS at allThe page names it a JWE with five partsThe payload is encrypted; read it where the decryption key lives

The order matters. Expiry and audience need no key and no cooperation from anybody, so they cost seconds to rule out; chasing a signature problem that turns out to be an aud mismatch is how an afternoon disappears.

Reading is not verifying

This is the distinction that catches people out. Decoding tells you what a token claims; it says nothing about whether those claims are genuine, because the header and payload are encoded, not encrypted, and anybody can write their own. Verification means recomputing the signature with the issuer's secret or public key — which this page will do in your browser — and it is the only step that turns a claim into a fact.

So use the decoded view to form a theory and the Verify button to test it, and never let an authorisation decision rest on decoded content in your own code. The Code tab prints the server-side check in eight languages for exactly that reason. If the encoding itself is what puzzles you, the difference between Base64 and Base64URL explains why a JWT segment cannot simply be pasted into an ordinary Base64 decoder.

Things that look like token problems and are not

  • The word Bearer copied along with the token, or a trailing newline from a terminal — both change the signing input and break the signature.
  • A token cut short by a log viewer. The signature segment is a fixed length per algorithm, so a truncated one fails every time.
  • Two services sharing a secret where one of them stores it Base64-encoded. Tick Secret is Base64 to reproduce that side.
  • A kid that no longer exists because the issuer rotated its keys; the token is fine, the key set is stale.

Once the token itself is cleared, the remaining suspects are on the server: a middleware that never validates, a clock that drifts, a cache holding an old key set. If you need a token in a known state to test any of that — expired, unexpired, signed with a key you control — the JWT generator will build one, and the expiry checker explains how a verifier reads the time claims.

Guides