Error message
Unable to find a signing key that matches: "2026-10"
Also printed as
- jwt.exceptions.PyJWKClientError: Unable to find a signing key that matches: "2026-10"
- Unable to find a signing key that matches: "None"
The quoted value is the token's `kid`; `"None"` means the header has no `kid`.
PyJWT (Python) — jwt.exceptions.PyJWKClientError from PyJWKClient.get_signing_key_from_jwt
What it means
`PyJWKClient` fetched the key set and found no signing key whose `kid` equals the token header's `kid` (shown in quotes). PyJWKClient refreshes the key set once when a `kid` is unknown, so the key really is not published at that URL right now. `"None"` in quotes means the token has no `kid` at all.
Why it happens
Signing key rotated before it was published
commonIf the issuer signs with a new key before adding it to the JWKS (or a CDN serves a stale copy of the JWKS), verifiers cannot find it. Issuers should publish the new key first and switch to it after caches expire.
The client points at another issuer's key set
commonTenant-specific JWKS URLs (Cognito user pools, Auth0 tenants, Keycloak realms, Entra ID tenants) look alike. A URL from another environment returns real keys — just not this token's.
The token header has no kid
occasional`PyJWKClient.get_signing_key_from_jwt` matches strictly by `kid`. Tokens from issuers that omit it cannot be resolved this way; verify with the single published key explicitly instead.
The key exists but is not a usable signing key
occasionalPyJWKClient considers only keys with `use` absent or `"sig"` that PyJWT can load; a key of an unsupported type is skipped. If the `kid` appears in the raw JSON but not in `get_signing_keys()`, this is why.
How to fix it
- 1.
Compare the token's kid with the loaded keys
`get_signing_keys(refresh=True)` shows exactly which keys PyJWKClient can use. If the token's `kid` is missing there, the issuer or the URL is the problem, not your code.
python print(jwt.get_unverified_header(token).get("kid")) for key in client.get_signing_keys(refresh=True): print(key.key_id, key.algorithm_name) - 2.
Reuse one PyJWKClient
Creating the client per request disables caching and hits the issuer on every call. A long-lived client with a key cache still refetches when a new `kid` appears.
python from jwt import PyJWKClient # Module level: one client, cached keys, refetch on an unknown kid. JWKS = PyJWKClient("https://issuer.example.com/.well-known/jwks.json", cache_keys=True, lifespan=600) def verify(token: str) -> dict: signing_key = JWKS.get_signing_key_from_jwt(token) return jwt.decode(token, signing_key.key, algorithms=["ES256"], audience="https://api.example.com")