Fehlermeldung
multiple matching keys found in the JSON Web Key Set
jose (JavaScript) — JWKSMultipleMatchingKeys, code ERR_JWKS_MULTIPLE_MATCHING_KEYS
Was der Fehler bedeutet
Mehr als ein Schlüssel im JSON Web Key Set könnte dieses Token prüfen, und jose weigert sich zu raten. Das passiert, wenn der Header des Tokens keinen `kid` hat (oder mehrere Schlüssel denselben `kid` teilen) und der Satz zwei oder mehr Schlüssel mit passendem Typ und passender Kurve enthält. jose probiert die Kandidaten innerhalb von `jwtVerify` absichtlich nicht für dich durch; der geworfene Fehler ist selbst ein asynchroner Iterator über die Kandidatenschlüssel, sodass du das Durchprobieren ausdrücklich aktivieren kannst.
Warum der Fehler auftritt
Der Aussteller schreibt keinen kid in den Header des Tokens
häufigViele kleine oder selbst geschriebene Aussteller signieren nur mit `{ "alg": "ES256" }`. Solange das JWKS einen einzigen Schlüssel enthält, funktioniert das; die erste Rotation, die einen zweiten Schlüssel veröffentlicht, legt jede prüfende Seite lahm.
Die veröffentlichten Schlüssel haben keinen kid
häufigSelbst wenn Tokens einen `kid` tragen, lässt sich ein JWKS, dessen Schlüsseln der `kid` fehlt, nicht über den Bezeichner zuordnen. Während einer Rotation enthält ein solcher Satz den ausscheidenden und den neuen Schlüssel, beide gleich plausibel.
Zwei Schlüssel teilen sich einen kid
gelegentlichManche Skripte für das Schlüsselmanagement leiten den `kid` aus einem festen Namen oder aus dem Algorithmus ab (`"es256"`) statt aus dem Schlüssel selbst, sodass alter und neuer Schlüssel am Ende denselben Bezeichner haben. Thumbprints nach RFC 7638 vermeiden das.
So behebst du den Fehler
- 1.
Signaturschlüssel in jedem Token kennzeichnen
Die robuste Lösung liegt beim Aussteller: Gib jedem Schlüssel einen eindeutigen `kid` (ein Thumbprint nach RFC 7638 eignet sich gut), veröffentliche ihn im JWKS und schreibe ihn in den geschützten Header jedes 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.
Kandidaten ausdrücklich durchprobieren
Kannst du den Aussteller nicht ändern, iteriere über den Fehler: jose liefert jeden Kandidatenschlüssel, und du akzeptierst das Token nur, wenn die Prüfung mit einem davon gelingt. Das kostet eine Signaturprüfung pro Kandidat, halte den Schlüsselsatz also klein.
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(); } }