Mensagem de erro
multiple matching keys found in the JSON Web Key Set
jose (JavaScript) — JWKSMultipleMatchingKeys, code ERR_JWKS_MULTIPLE_MATCHING_KEYS
O que significa
Mais de uma chave do conjunto de chaves (JSON Web Key Set) poderia verificar este token, e o jose se recusa a adivinhar. Isso acontece quando o cabeçalho do token não tem `kid` (ou várias chaves compartilham o mesmo `kid`) e o conjunto contém duas ou mais chaves do tipo e da curva certos. O jose deliberadamente não testa as candidatas por você dentro de `jwtVerify`; o próprio erro lançado é um iterador assíncrono sobre as chaves candidatas, então você pode optar explicitamente por testá-las.
Por que acontece
O emissor não coloca o kid no cabeçalho do token
comumMuitos emissores pequenos ou escritos à mão assinam apenas com `{ "alg": "ES256" }`. Enquanto o JWKS tem uma única chave, isso funciona; a primeira rotação que publica uma segunda chave quebra todos os verificadores.
As chaves publicadas não têm kid
comumMesmo que os tokens tragam um `kid`, as chaves de um JWKS sem `kid` não podem ser associadas pelo identificador. Durante a rotação, esse conjunto contém a chave que está saindo e a que está entrando, ambas igualmente plausíveis.
Duas chaves compartilham o mesmo kid
ocasionalAlguns scripts de gerenciamento de chaves derivam o `kid` de um nome fixo ou do algoritmo (`"es256"`) em vez da própria chave, e assim a chave antiga e a nova acabam com o mesmo identificador. As impressões digitais (thumbprints) da RFC 7638 evitam isso.
Como corrigir
- 1.
Identificar a chave de assinatura em todos os tokens
A correção robusta fica no emissor: dê a cada chave um `kid` único (uma impressão digital da RFC 7638 funciona bem), publique-o no JWKS e escreva-o no cabeçalho protegido de todos os tokens.
js import { SignJWT } from "jose"; // Issuer side: name the key in every token, and publish the same kid in the JWKS. const token = await new SignJWT(claims) .setProtectedHeader({ alg: "ES256", kid: "2026-10" }) .setExpirationTime("10m") .sign(privateKey); - 2.
Optar por testar as candidatas
Quando não for possível mudar o emissor, itere sobre o erro: o jose entrega cada chave candidata, e você só aceita o token se a verificação com uma delas for bem-sucedida. Isso custa uma verificação de assinatura por candidata, então mantenha o conjunto de chaves pequeno.
js import { errors, jwtVerify } from "jose"; async function verifyWithCandidates(token, jwks, options) { try { return await jwtVerify(token, jwks, options); } catch (err) { if (err?.code !== "ERR_JWKS_MULTIPLE_MATCHING_KEYS") throw err; for await (const publicKey of err) { try { return await jwtVerify(token, publicKey, options); } catch (inner) { if (inner?.code === "ERR_JWS_SIGNATURE_VERIFICATION_FAILED") continue; throw inner; } } throw new errors.JWSSignatureVerificationFailed(); } }