Debugging JSON Web Token issues can be frustrating. Cryptographic operations fail silently or throw cryptic errors like invalid signature without indicating whether the issue is an encoding bug, an incorrect secret, or clock drift.

This guide breaks down the 6 most common JWT errors, explaining the root cause behind each failure and providing exact code fixes.

1. Error: "JsonWebTokenError: invalid signature"

This is the most frequent error encountered in JWT verification. It means the signature computed by the server does not match the signature provided in the third part of the token.

🛠️ JWT Error Diagnostic & Troubleshooting Matrix

Diagnostic Flow
invalid signature Root Causes: • Wrong secret / public key • Base64URL vs Hex encoding • Trailing newline / whitespace Fix: Verify on jwtdebug.dev jwt expired Root Causes: • Timestamp > "exp" claim • Server clock drift / NTP out • Milliseconds vs seconds Fix: clockTolerance: 60s jwt malformed Root Causes: • Did not strip "Bearer " • Missing 3-part dot structure • Invalid Base64URL padding Fix: strip Bearer prefix
Figure 1: Quick diagnostic matrix for resolving the top three most common JSON Web Token verification errors.

Common Causes & Solutions:

2. Error: "TokenExpiredError: jwt expired"

The current time is greater than the timestamp recorded in the token's exp (expiration) claim.

Common Causes & Solutions:

3. Error: "JsonWebTokenError: jwt malformed"

The token structure does not conform to the required header.payload.signature tripartite layout.

Common Causes & Solutions:

4. Error: "JsonWebTokenError: invalid algorithm"

The verification library was instructed to allow only specific algorithms, and the incoming token's header specifies a different or unauthorized algorithm.

Fix: Align Algorithm Whitelist
// If token was signed with RS256:
jwt.verify(token, publicKey, {
  algorithms: ["RS256"] // Make sure token header also specifies "alg": "RS256"
});

5. Error: "jwt audience invalid" / "jwt issuer invalid"

The signature was valid, but claim validation failed.

Common Causes & Solutions:

6. Base64 vs. Base64URL Encoding Issues

Standard Base64 uses characters + and /, and pads with =. JWTs require Base64URL encoding, which replaces + with -, / with _, and removes all padding = characters. If you decode or encode manually with naive atob() or btoa(), URL characters will be corrupted.