Skip to content
ecdsa.com
jose (JavaScript)JWKS and key discovery

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

How to fix it

  1. 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. 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. 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

Browse the full signature error database