Mensagem de erro
Unable to find a signing key that matches: "2026-10"
Também aparece como
- jwt.exceptions.PyJWKClientError: Unable to find a signing key that matches: "2026-10"
- Unable to find a signing key that matches: "None"
O valor entre aspas é o `kid` do token; `"None"` significa que o cabeçalho não tem `kid`.
PyJWT (Python) — jwt.exceptions.PyJWKClientError from PyJWKClient.get_signing_key_from_jwt
O que significa
O `PyJWKClient` baixou o conjunto de chaves e não encontrou nenhuma chave de assinatura cujo `kid` seja igual ao `kid` do cabeçalho do token (mostrado entre aspas). O PyJWKClient atualiza o conjunto de chaves uma vez quando um `kid` é desconhecido, então a chave realmente não está publicada nessa URL no momento. `"None"` entre aspas significa que o token não tem `kid` nenhum.
Por que acontece
Chave de assinatura rotacionada antes de ser publicada
comumSe o emissor assina com uma chave nova antes de adicioná-la ao JWKS (ou se uma CDN serve uma cópia desatualizada do JWKS), os verificadores não conseguem encontrá-la. Convém que os emissores publiquem primeiro a chave nova e só passem a usá-la depois que os caches expirarem.
O cliente aponta para o conjunto de chaves de outro emissor
comumURLs de JWKS específicas de cada tenant (user pools do Cognito, tenants do Auth0, realms do Keycloak, tenants do Entra ID) são parecidas. Uma URL de outro ambiente retorna chaves reais — só que não as deste token.
O cabeçalho do token não tem kid
ocasional`PyJWKClient.get_signing_key_from_jwt` faz a correspondência estritamente pelo `kid`. Tokens de emissores que o omitem não podem ser resolvidos assim; nesse caso, verifique explicitamente com a única chave publicada.
A chave existe, mas não é uma chave de assinatura utilizável
ocasionalO PyJWKClient considera apenas chaves em que `use` está ausente ou vale `"sig"` e que o PyJWT consegue carregar; uma chave de um tipo sem suporte é ignorada. Se o `kid` aparece no JSON bruto, mas não em `get_signing_keys()`, o motivo é este.
Como corrigir
- 1.
Comparar o kid do token com as chaves carregadas
`get_signing_keys(refresh=True)` mostra exatamente quais chaves o PyJWKClient consegue usar. Se o `kid` do token não estiver ali, o problema é o emissor ou a URL, não o seu código.
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.
Reutilizar um único PyJWKClient
Criar o cliente a cada requisição desativa o cache e aciona o emissor em toda chamada. Um cliente de longa duração com cache de chaves continua buscando as chaves de novo quando aparece um `kid` novo.
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")