Error message
no applicable key found in the JSON Web Key Set
jose (JavaScript) — JWKSNoMatchingKey, code ERR_JWKS_NO_MATCHING_KEY
What it means
jose looked through the JSON Web Key Set you gave it and found no key that may verify this token. A key qualifies only if all of these hold: its `kid` equals the token header's `kid` (when the token has one), its `kty` fits the token's `alg`, its `alg` (if present) equals the token's `alg`, its `crv` matches (P-256 for ES256), `use` is absent or `"sig"`, and `key_ops` (if present) includes `"verify"`. No cryptography ran — the failure is in key selection.
Why it happens
The issuer rotated its signing key
commonNew tokens carry a new `kid` that the cached or hard-coded key set does not contain yet. This is the most frequent cause and usually starts at the exact minute of a rotation; services restarted later work, older ones fail.
The key set belongs to another issuer or environment
commonA staging JWKS URL in production, the JWKS of a different tenant, or a key set copied from documentation. Every `kid` looks plausible, none matches.
Key metadata contradicts the token
occasionalThe JWK has `alg: "RS256"` while the token is ES256, or the EC key is on P-384 while the token uses ES256 (which requires P-256). jose skips such keys even when the `kid` matches, because using a key for a different algorithm is exactly what JWK metadata exists to prevent.
The key is marked for encryption
occasionalA key published with `use: "enc"` or with `key_ops` that lack `"verify"` is not a signature-verification key. Some providers publish both kinds in one set; only the `sig` keys can verify tokens.
A local copy of the JWKS was never refreshed
occasional`createLocalJWKSet` uses the keys you pass, forever. If the set came from a file or an environment variable at deploy time, it silently goes out of date with the next rotation.
How to fix it
- 1.
Compare the token's kid with the published keys
Decode the protected header and list the published keys with their `kid`, `alg`, `kty`, `crv` and `use`. If the `kid` is absent from the set, you are looking at a rotation or the wrong key set; if it is present, look at the metadata fields.
bash # kid and alg the token asks for python3 -c 'import base64,json,sys; h=sys.argv[1].split(".")[0]; print(json.loads(base64.urlsafe_b64decode(h + "=" * (-len(h) % 4))))' "$TOKEN" # kid, alg, kty, crv, use of every key the issuer publishes curl -s https://issuer.example.com/.well-known/jwks.json | jq '.keys[] | {kid, alg, kty, crv, use}' - 2.
Fetch the issuer's JWKS instead of pinning keys
`createRemoteJWKSet` caches the keys and refetches the set when a token names a `kid` it has not seen, so rotations are picked up automatically without accepting arbitrary keys.
js import { createRemoteJWKSet, jwtVerify } from "jose"; // Fetches the JWKS, caches it, and refetches when a token names an unknown kid // (at most once per cooldownDuration, 30 s by default). const jwks = createRemoteJWKSet(new URL("https://issuer.example.com/.well-known/jwks.json")); const { payload } = await jwtVerify(token, jwks, { algorithms: ["ES256"], issuer: "https://issuer.example.com", }); - 3.
Publish keys with consistent metadata
If you run the issuer, make sure each signing key has a unique `kid`, `use: "sig"`, and an `alg` and `crv` that match the tokens it signs. Publish the new key before you start signing with it.
json { "keys": [ { "kty": "EC", "crv": "P-256", "kid": "2026-10", "use": "sig", "alg": "ES256", "x": "…", "y": "…" } ] }
Related errors
multiple matching keys found in the JSON Web Key Setjose (JavaScript)Unable to find a signing key that matches '2026-10-rotated'jwks-rsa (Node.js)IDX10503: Signature validation failed. The token's kid is: '2026-10', but did n…Microsoft.IdentityModel.JsonWebTokens / System.IdentityModel.Tokens.Jwt (.NET)signature verification failedjose (JavaScript)