Error Encyclopedia

JWT Invalid Signature Error

Fix 'invalid signature' JWT errors. Learn how JWT signatures work, why they fail, and how to use the correct secret key.

What Does This Error Mean?

The 'invalid signature' error occurs when the JWT library tries to verify the token's signature but the computed signature does not match the one embedded in the token. This usually means the token was signed with a different secret or key than the one being used for verification.

Common Causes

1

Using the wrong secret or private key for token verification

2

Secret was rotated but old tokens are still in circulation

3

Token was tampered with (payload modified after signing)

4

Algorithm confusion attack (token uses 'none' algorithm but verifier expects signed)

5

Using HMAC (symmetric) when token was signed with RSA (asymmetric) and vice versa

6

Encoding mismatch (UTF-8 vs ASCII) in the secret

How to Fix It

Verify the signing secret

Ensure the secret used for verification matches the one used for signing.

// ❌ Different secrets
const secret = "my-secret-key"
const token = jwt.sign({ id: 1 }, "wrong-secret") // Signed with different secret
jwt.verify(token, secret) // Throws: invalid signature

// ✅ Same secret
const token = jwt.sign({ id: 1 }, secret)
jwt.verify(token, secret) // Passes

Rotate secrets gracefully

When rotating secrets, keep the old secret valid for a transition period.

const secrets = [
  { key: process.env.JWT_SECRET_NEW, active: true },
  { key: process.env.JWT_SECRET_OLD, active: false },
]

function verifyToken(token) {
  for (const { key } of secrets) {
    try { return jwt.verify(token, key) }
    catch (e) { continue }
  }
  throw new Error("Invalid token with all keys")
}

Prevent algorithm confusion

Always specify the allowed algorithms when verifying to prevent 'none' algorithm attacks.

// Explicitly set allowed algorithms
jwt.verify(token, secret, {
  algorithms: ["HS256"] // Only allow HMAC-SHA256
})

// ❌ Never do this
jwt.verify(token, secret) // Implicit algorithm may allow "none"

Related Tools

Use these tools to debug and fix this error:

Related Guides

Deepen your understanding with these guides and tutorials:

Related Errors

Other common errors in this category:

Frequently Asked Questions

Can a JWT be decoded without the secret?

Yes. JWT payload is only Base64URL-encoded, not encrypted. Anyone can decode (base64 decode) the payload. The signature is what verifies the payload hasn't been tampered with.

What is the algorithm confusion attack?

An attacker changes the JWT header's 'alg' field from 'RS256' to 'HS256' and signs it with the public key (which is public). If the verifier implicitly trusts the algorithm, this bypasses signature verification.