JWT verification failed: no matching key found in JWKS for kid 'abc123'
ID: security/oauth2-jwk-set-without-kid
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| jsonwebtoken 8.5.1 | active | — | — | — |
| jose 4.14.4 | active | — | — | — |
| Keycloak 20.0.0 | active | — | — | — |
| Auth0 Node.js SDK 3.0.0 | active | — | — | — |
Root Cause
The JWT contains a 'kid' header that does not match any key ID in the JSON Web Key Set (JWKS) fetched from the identity provider, often due to caching stale JWKS or misconfigured key rotation.
generic中文
JWT的'kid'头与从身份提供者获取的JSON Web Key Set(JWKS)中的任何密钥ID都不匹配,通常是由于JWKS缓存过期或密钥轮换配置错误。
Official Documentation
https://auth0.com/docs/secure/tokens/json-web-tokens/validate-json-web-tokensWorkarounds
-
80% success Refresh the JWKS cache before validation. In Node.js with jose library, set a shorter cache duration and force refresh on error: `const keys = await client.getSigningKeys(true);`
Refresh the JWKS cache before validation. In Node.js with jose library, set a shorter cache duration and force refresh on error: `const keys = await client.getSigningKeys(true);`
-
75% success Ensure the identity provider's JWKS endpoint is reachable and the 'kid' values align. Use `curl https://your-idp.com/.well-known/jwks.json` and compare the 'kid' values with the token header.
Ensure the identity provider's JWKS endpoint is reachable and the 'kid' values align. Use `curl https://your-idp.com/.well-known/jwks.json` and compare the 'kid' values with the token header.
-
70% success Implement a fallback: if 'kid' is missing in the JWT, try all keys in the JWKS to find a match. This handles legacy tokens but should be deprecated for security.
Implement a fallback: if 'kid' is missing in the JWT, try all keys in the JWKS to find a match. This handles legacy tokens but should be deprecated for security.
中文步骤
在验证之前刷新JWKS缓存。在Node.js中使用jose库时,设置较短的缓存持续时间并在出错时强制刷新:`const keys = await client.getSigningKeys(true);`
确保身份提供者的JWKS端点可访问且'kid'值一致。使用`curl https://your-idp.com/.well-known/jwks.json`并将'kid'值与令牌头进行比较。
实现回退机制:如果JWT中缺少'kid',尝试使用JWKS中的所有密钥进行匹配。这可以处理旧令牌,但出于安全考虑应弃用。
Dead Ends
Common approaches that don't work:
-
40% fail
Restarting the server only clears the in-memory cache, but if the JWKS is cached in a shared store like Redis, the stale keys persist and the error remains.
-
60% fail
Hardcoding the public key in the code bypasses the JWKS entirely, but it breaks when the identity provider rotates keys, leading to future authentication failures.
-
90% fail
Disabling JWT signature validation entirely removes the security check, leaving the application vulnerable to forged tokens and is never an acceptable fix.