JWT Signature Verification Failed — Causes & Fixes
A JWT can decode perfectly (header and payload are just Base64URL-encoded JSON, no secret required) while its signature still fails verification. Decoding success tells you nothing about whether the token is trustworthy.
Check these in order
1. Wrong secret or key
By far the most common cause. For HMAC algorithms (HS256/384/512), the exact same secret used to sign must be used to verify — a single wrong character fails silently with no useful error, just "invalid signature." For RS/ES algorithms, make sure you're verifying with the public key that corresponds to the private key that signed it, not a key from a different key pair or environment (dev vs. prod key mismatches are common).
2. Algorithm mismatch
The alg in the header must match the algorithm you're verifying with. If a token was signed HS256 and you try to verify it as HS384, it will fail even with the "right" secret, because the hash function differs.
3. The payload was re-encoded
JSON key order isn't guaranteed to survive a decode-then-re-encode round trip in every language/library. If something in your pipeline decodes the payload, changes nothing, and re-encodes it before the signature is checked, the re-serialized bytes can differ from the original signed bytes even though the data looks identical — and the signature won't match.
4. Whitespace or line breaks were introduced
If a JWT gets copy-pasted through a UI, logged, or stored in a system that wraps long lines, stray whitespace or newlines inserted into the token string will break the signature check the moment they're included in the verified input.
5. Clock-based claims, not the signature itself
Confusingly, some libraries report "invalid token" for an expired token even when the signature is actually valid. Check exp and nbf separately from signature validity — Cryonel's JWT Decoder reports these as distinct issues rather than lumping them together.
Debug it
Paste the token and your secret or public key PEM into the JWT Decoder — it verifies HS256/384/512, RS256/384/512, and ES256/384, and tells you specifically whether the signature matched, independent of whether claims like exp are valid.