"JWKS Key Not Found" / kid Mismatch, Explained
This means the token's header points at a key that isn't (or is no longer) in the identity provider's published key set — a different failure mode from a bad signature or an expired token.
What triggers it
A JWT signed with RS256/ES256 etc. carries a kid (key ID) in its header identifying which public key to verify it against:
{
"alg": "RS256",
"kid": "2024-03-key-1",
"typ": "JWT"
}
The verifier fetches the identity provider's JWKS (usually at /.well-known/jwks.json) and looks for an entry with a matching kid. If none exists, verification fails before the signature is even checked — there's no key to check it against.
Why this usually means key rotation
Identity providers rotate signing keys periodically for security, publishing a new key and eventually retiring the old one from the JWKS. If a token was signed with a key that's since been retired — or if your app cached an old JWKS and hasn't refreshed it — you'll see exactly this error. It's rarely a sign of a forged token; it's almost always a caching or timing issue.
How to debug it
- Decode the token's header (without verifying) in the JWT Decoder to read its
kid. - Fetch the current JWKS from the provider's
/.well-known/jwks.jsonendpoint and paste it into the JWKS Inspector to list everykidcurrently published. - If the token's
kidisn't in that list, the token was signed with a retired key — it needs to be re-issued, not "fixed." - If your application caches the JWKS, make sure it refreshes periodically (most JWT libraries support this) rather than fetching it once at startup.