ory/hydra · error

unable to find JSON Web Key with ID: %s

Error message

unable to find JSON Web Key with ID: %s

What it means

Fetcher.GetKey looks up the requested key ID (kid) in the cache after (possibly) fetching the remote JWKS. If the fetched key set contains no key whose KeyID equals kid, it errors with this message. The set was fetched fine; the specific kid simply is not published there.

Source

Thrown at oryx/jwksx/fetcher.go:73

	var set jose.JSONWebKeySet
	if err := json.NewDecoder(res.Body).Decode(&set); err != nil {
		return nil, errors.WithStack(err)
	}

	for _, k := range set.Keys {
		f.Lock()
		f.keys[k.KeyID] = k
		f.Unlock()
	}

	f.RLock()
	defer f.RUnlock()
	if k, ok := f.keys[kid]; ok {
		return &k, nil
	}

	return nil, errors.Errorf("unable to find JSON Web Key with ID: %s", kid)
}

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Refresh the key set (create a new Fetcher or clear the cache) in case it is stale relative to the signing key rotation.
  2. Verify the JWKS URL matches the issuer that actually signed the token (check token 'iss' and discovery 'jwks_uri').
  3. Compare the token header 'kid' against the kids in the fetched JWKS (jose.JSONWebKeySet) to confirm the mismatch.
  4. Ensure you are verifying a token from the right environment/tenant; cross-environment tokens will never match.

Example fix

// before
key, err := fetcher.GetKey(tokenKid) // stale cache
// after
fetcher = jwksx.NewFetcher(remoteJWKSURL) // re-fetch fresh keys
key, err := fetcher.GetKey(tokenKid)
Defensive patterns

Strategy: fallback

Validate before calling

set, _ := fetchRemoteJWKS(jwksURL)
if !containsKid(set.Keys, tokenHeader.Kid) {
    return fmt.Errorf("kid %s not present at %s; check issuer/rotation", tokenHeader.Kid, jwksURL)
}

Try / catch

key, err := fetcher.GetKey(kid)
if err != nil {
    fetcher = jwksx.NewFetcher(remoteURL) // refresh cache once
    key, err = fetcher.GetKey(kid)
    if err != nil { return fmt.Errorf("unknown kid %q for issuer", kid) }
}

Prevention

When it happens

Trigger: Calling Fetcher.GetKey(kid) (oryx/jwksx/fetcher.go:73) with a kid that does not exist in the remote JWKS — typically a kid taken from a token's JWT header that the fetched key set never contained.

Common situations: Verifying tokens signed with a rotated-out key after the JWKS was refreshed; using the wrong issuer's JWKS URL; stale local cache that was populated before rotation; tokens minted by a different environment (staging token verified against prod keys).

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/fab63b81c5f3be4f. Report an issue: GitHub.