Fix Common JWT Token Decoding Errors
Debug JWT decode failures, expired token errors, signature validation issues, malformed headers, and algorithm confusion attacks.
JWT tokens are three Base64url-encoded segments joined by dots. Each segment has strict rules, and a single character off breaks the entire token. This guide covers the seven most common JWT errors developers encounter.
Jump to error
Token is malformed (not three parts)
JsonWebTokenError: jwt malformed
A valid JWT must have exactly three dot-separated segments: header.payload.signature. Missing dots or extra content breaks the structure.
Step-by-step fix
- 1 Paste the full token — including all three parts separated by periods.
- 2 Check you haven't accidentally included the 'Bearer ' prefix.
- 3 Verify no line breaks were introduced when copying the token.
- 4 Count the dots: a valid JWT has exactly two.
Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.signature
Token has expired
TokenExpiredError: jwt expired (exp claim)
The `exp` claim is a Unix timestamp in seconds. When the current time exceeds this value, the token is invalid.
Step-by-step fix
- 1 Paste the token into the JWT Decoder.
- 2 Inspect the `exp` field in the payload — it's a Unix timestamp.
- 3 Use the Timestamp Converter to check what date that corresponds to.
- 4 Request a new token from your auth server; do not extend the exp manually.
// exp: 1700000000 — already in the past
{"sub": "user_123", "exp": 1700000000}
// exp should be current_time + token_lifetime
{"sub": "user_123", "exp": 1893456000}
Algorithm mismatch (none or RS256 vs HS256)
JsonWebTokenError: invalid algorithm
The `alg` field in the JWT header must match the algorithm your server expects. The 'none' algorithm attack and RS256/HS256 confusion are common security issues.
Step-by-step fix
- 1 Decode the header (first segment) in the JWT Decoder.
- 2 Check the `alg` field — compare it to your server's expected algorithm.
- 3 Never accept tokens with `"alg": "none"` in production.
- 4 If using RS256, ensure you validate with the public key, not the HMAC secret.
// Attacker-crafted token:
{"alg": "none", "typ": "JWT"}
// Valid production header:
{"alg": "HS256", "typ": "JWT"}
Base64url padding causes decode error
Error: Invalid base64url string
JWT uses Base64url encoding (no `+` or `/`, no `=` padding). Standard Base64 decoders reject this format.
Step-by-step fix
- 1 Use the JWT Decoder tool which handles Base64url automatically.
- 2 If decoding manually, replace `-` with `+` and `_` with `/`.
- 3 Add padding: append `=` until the string length is a multiple of 4.
// Standard base64 decode fails on JWT segments atob(jwtSegment.replace(/-/g, '+').replace(/_/g, '/')) // missing padding
function decodeJwtSegment(seg) {
const pad = seg + '==='.slice((seg.length + 3) % 4);
return atob(pad.replace(/-/g, '+').replace(/_/g, '/'));
}
Decoding succeeds but claims are not validated
(No error — silent security bypass)
The JWT Decoder only decodes — it does not verify the signature or validate claims. Never trust decoded claims without server-side signature verification.
Step-by-step fix
- 1 Use the decoder only for debugging/inspection.
- 2 In production, always verify the signature using your auth library.
- 3 Validate `iss` (issuer), `aud` (audience), and `exp` claims server-side.
- 4 Never use decoded payload data without verification.
// INSECURE: trusting decoded JWT without verification
const payload = JSON.parse(atob(token.split('.')[1]));
const userId = payload.sub; // NEVER do this
// SECURE: verify first, then use const payload = jwt.verify(token, SECRET_KEY); const userId = payload.sub;
Frequently Asked Questions
Is it safe to paste my JWT token into the online decoder?
The JWT Decoder on toolpilot.dev runs entirely in your browser — no data is sent to any server. That said, avoid pasting production tokens with sensitive claims; use test tokens for debugging.
Why does my token decode fine locally but fail in production?
Common causes: clock skew (server time differs by more than the token's leeway), wrong secret key, or a different algorithm than expected. Check the `iat`, `exp`, and `alg` claims.
What is the difference between a JWT and a session token?
A JWT is self-contained — all claims are in the token itself. A session token is an opaque reference that requires a database lookup. JWTs are stateless but cannot be revoked without a blacklist.
Related Tools
Try the JWT Decoder now
Free, runs in your browser, no signup required. Learn more about JWT Decoder.
Open JWT Decoder →