A JWT is three Base64url segments joined by dots: header, payload, signature. The first two are plain JSON that anyone can read without the secret. That makes decoding the fastest way to answer "why is this token rejected", usually because exp is in the past or aud is wrong.
What you'll learn
- Split a JWT into header, payload and signature
- Read standard claims: sub, iss, aud, exp, iat, nbf
- Turn the 10-digit timestamps into dates and spot an expired token
Step by step
-
Paste the token
Open the JWT Decoder and paste the full token. It must have exactly three dot-separated parts.
-
Read header and payload
The header shows the algorithm (alg) and type. The payload holds the claims. Both are pretty-printed JSON.
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJleHAiOjE2MDAwMDAwMDB9.sig Header: { "alg": "HS256" } Payload: { "sub": "123", "exp": 1600000000 } -
Check the timeline
exp and iat are Unix timestamps in seconds. The tool converts them and labels the token Expired when exp is in the past, which is the answer to most 401 errors.
-
Verify separately
Decoding proves nothing about authenticity. Verification needs the secret or public key and happens in your backend or identity provider.
Common problems
A segment is not valid Base64url JSON
The token was truncated or altered, often by a copy that dropped characters or added a newline. Copy it again from the source.
The token is not expired but is still rejected
Check aud and iss match what the server expects, that nbf is not in the future, and that clocks agree; a few seconds of skew can matter.
FAQ
Is my token sent to a server?
No, decoding is local. Even so, production tokens are credentials; avoid pasting them into tools you do not trust.
Why can I read the payload without the secret?
Because JWTs are signed, not encrypted. The signature detects tampering; it does not hide the content.