Fix JWT Verification Failures & Token Expiration Errors
Debug JWT signature verification failures, expired tokens, algorithm mismatches, and claim validation errors. Decode and inspect tokens step by step.
JWT (JSON Web Token) verification failures are one of the most frustrating authentication debugging tasks. A tiny mismatch in algorithm, key format, or clock skew can break your entire auth flow. This guide walks through every common JWT error and how to diagnose it.
Common errors covered
JWT signature verification failed
JsonWebTokenError: invalid signature
jwt.exceptions.InvalidSignatureError: Signature verification failed
The signature does not match the header + payload when verified with the given secret/key. Common causes: wrong secret, algorithm mismatch (HS256 vs RS256), or the token was modified after signing.
Step-by-step fix
- 1 Paste your JWT into the JWT Decoder to inspect header and payload.
-
2
Check the
algfield in the header - does it match your server's expected algorithm? - 3 Verify you are using the correct secret (for HMAC) or public key (for RSA/ECDSA).
- 4 Ensure the token has not been truncated or modified (check for whitespace or newline characters).
- 5 If using RS256: confirm you are verifying with the public key, not the private key.
// Using wrong algorithm
jwt.verify(token, publicKey, { algorithms: ['HS256'] })
// But token was signed with RS256!
// Match the algorithm to the token header
jwt.verify(token, publicKey, { algorithms: ['RS256'] })
JWT token expired (exp claim)
TokenExpiredError: jwt expired
jwt.exceptions.ExpiredSignatureError: Signature has expired
The token's exp (expiration) claim is a Unix timestamp that has passed. This is normal behavior. The issue is usually that your refresh logic is not working or there is clock skew between servers.
Step-by-step fix
-
1
Decode the token with our JWT Decoder and find the
expfield. -
2
Convert the
exptimestamp using our Timestamp Converter. - 3 Compare with current time - if expired, you need a fresh token.
- 4 Check your token refresh logic - is it running before expiration?
-
5
Consider adding a
clockToleranceoption (e.g., 30 seconds) to handle clock skew.
// No expiration handling const decoded = jwt.verify(token, secret);
// Handle expiration gracefully
try {
const decoded = jwt.verify(token, secret, { clockTolerance: 30 });
} catch (err) {
if (err.name === 'TokenExpiredError') {
const newToken = await refreshToken();
}
}
Malformed JWT structure (not three parts)
JsonWebTokenError: jwt malformed
ValueError: Not enough segments
A valid JWT has exactly three Base64-encoded parts separated by dots: header.payload.signature. If any part is missing or the token contains extra characters, it will fail to parse.
Step-by-step fix
- 1 Count the dots in your token - there should be exactly 2.
-
2
Check if the
Bearerprefix was accidentally included in the token value. - 3 Ensure no line breaks or spaces are embedded in the token string.
- 4 Paste into the JWT Decoder - it will show which part is invalid.
// Including 'Bearer' prefix in the token const token = 'Bearer eyJhbGciOi...'; jwt.verify(token, secret);
// Strip the Bearer prefix
const authHeader = req.headers.authorization;
const token = authHeader.split(' ')[1];
jwt.verify(token, secret);
Prevention Tips
- Always decode and inspect JWTs during development using the JWT Decoder.
-
Set reasonable expiration times (
exp) and implement token refresh logic. - Explicitly specify allowed algorithms to prevent algorithm confusion attacks.
-
Use
nbf(not-before) andiss(issuer) claims for additional validation.
Frequently Asked Questions
Is it safe to paste my JWT into an online decoder?
Yes. Our JWT Decoder runs 100% in your browser. The token is never sent to any server. For production tokens, you can verify this in your browser Network tab.
What is the difference between HS256 and RS256?
HS256 uses a shared secret (same key to sign and verify). RS256 uses a private key to sign and a public key to verify. RS256 is preferred for distributed systems where you do not want to share the signing key.
How long should JWT tokens be valid?
Access tokens: 15 minutes to 1 hour. Refresh tokens: 7-30 days. Short-lived access tokens limit damage if compromised; refresh tokens keep users logged in.
Related Error Guides
Related Tools
Still stuck? Try our free tools
All tools run in your browser, no signup required.