错误信息
Unable to find a signing key that matches '2026-10-rotated'
也可能输出为
- error in secret or public key callback: Unable to find a signing key that matches '2026-10-rotated'
- SigningKeyNotFoundError: Unable to find a signing key that matches
- No KID specified and JWKS endpoint returned more than 1 key
引号中的值是令牌的 `kid`(如果头部中没有,则为 `'undefined'`)。通过带回调的 `jwt.verify()` 调用时,文本前面会加上“error in secret or public key callback: ”。不带 `kid` 的令牌遇到包含多个密钥的密钥集时,会报错“No KID specified and JWKS endpoint returned more than 1 key”。
jwks-rsa (Node.js) — SigningKeyNotFoundError, often wrapped by jsonwebtoken or express-jwt
含义
jwks-rsa 下载了密钥集,但其中没有任何一个可用的签名密钥带有令牌头部中的 `kid`(即引号中的值)。令牌本身可能完全有效——只是验证方没有签名它的那个密钥。通过 jsonwebtoken 的密钥回调使用 jwks-rsa 时,消息前面会加上“error in secret or public key callback:”前缀。
原因
密钥轮换与缓存的密钥集
常见提供商开始用新密钥签名。遇到未知的 `kid` 时,jwks-rsa 会重新获取密钥集,但前提是缓存和速率限制允许;缓存时间设得很长的客户端,或者手动复制的密钥,在重启之前会一直失败。
JWKS URL 属于另一个租户或环境
常见Auth0 租户、Cognito 用户池、Entra ID 租户和 Keycloak 领域(realm)都各自拥有密钥集。在生产环境中使用预发布环境的 `jwksUri`,得到的密钥 `kid` 值看起来有效,实际上却不同。
匹配的密钥被过滤掉了
偶见jwks-rsa 只考虑满足以下条件的密钥:`use` 不存在或为 `"sig"`,`kty` 为 RSA、EC 或 OKP,并且能导入为公钥。以 `use: "enc"` 发布的密钥或格式错误的 JWK,即使 `kid` 匹配,也会被静默跳过。
令牌由另一个提供商签发
偶见来自另一个身份提供商的令牌(或者你为测试在本地签发的令牌)所指定的密钥,这个提供商从未发布过。排查密钥之前,先检查载荷中的 `iss`。
修复方法
- 1.
列出已发布的 kid
解码令牌头部,把其中的 `kid` 与 `jwksUri` 处的密钥对比。如果 `kid` 在其中,错误却依然存在,说明该密钥被过滤掉了——检查它的 `use` 和 `kty`。
bash # kids the provider publishes (jwks-rsa ignores keys with use "enc" and non RSA/EC/OKP keys) curl -s https://tenant.example.com/.well-known/jwks.json | jq '.keys[] | {kid, kty, use, alg}' - 2.
创建一个启用缓存和速率限制的客户端
启用缓存的模块级客户端会在出现新的 `kid` 时重新获取密钥集;当攻击者发送随机 `kid` 值时,它还能保护提供商免受大量请求的冲击。
js import jwksRsa from "jwks-rsa"; // One client per process; unknown kids trigger a refetch, bounded by the rate limit. export const jwksClient = jwksRsa({ jwksUri: "https://tenant.example.com/.well-known/jwks.json", cache: true, cacheMaxAge: 10 * 60 * 1000, rateLimit: true, jwksRequestsPerMinute: 10, });
相关错误
no applicable key found in the JSON Web Key Setjose (JavaScript)Unable to find a signing key that matches: "2026-10"PyJWT (Python)IDX10503: Signature validation failed. The token's kid is: '2026-10', but did n…Microsoft.IdentityModel.JsonWebTokens / System.IdentityModel.Tokens.Jwt (.NET)Jwks doesn't have key to match kid or alg from JwtEnvoy / Istio