Error message
token is unverifiable: error while executing keyfunc: kid "2026-10" not found in key set
Also printed as
- token is unverifiable: error while executing keyfunc
- token is unverifiable: no keyfunc was provided
The text after "error while executing keyfunc:" is whatever your Keyfunc returned. Calling `jwt.Parse` with a nil Keyfunc gives "token is unverifiable: no keyfunc was provided".
golang-jwt/jwt (Go) — jwt.ErrTokenUnverifiable wrapping the error your Keyfunc returned
What it means
golang-jwt could not obtain a key to verify the token: your `Keyfunc` returned an error, and golang-jwt wrapped it as `ErrTokenUnverifiable` ("error while executing keyfunc: …"). Everything after that prefix is your own Keyfunc's message — in the reproduction, a key lookup by `kid` that found nothing. The token was neither verified nor rejected on its merits.
Why it happens
The token names a key the service does not have
commonKeys loaded once at startup go stale after the issuer rotates. A `kid` from another environment or issuer produces the same lookup failure.
The key set could not be fetched
commonKeyfuncs that download the JWKS on demand return network errors (DNS, TLS, timeouts, HTTP 404) through this path. The wrapped message names the real failure.
No Keyfunc was passed
occasional`jwt.Parse(token, nil)` or a Keyfunc variable that was never initialised. golang-jwt cannot verify anything without a key source.
How to fix it
- 1.
Use a refreshing JWKS Keyfunc
A JWKS-backed Keyfunc refreshes keys in the background and when an unknown `kid` appears, so rotations do not cause outages.
go k, err := keyfunc.NewDefaultCtx(ctx, []string{"https://issuer.example.com/.well-known/jwks.json"}) if err != nil { log.Fatalf("load JWKS: %v", err) } // Refetches the JWKS in the background and on unknown kids (rate-limited). token, err := jwt.Parse(raw, k.Keyfunc, jwt.WithValidMethods([]string{"ES256"})) - 2.
Log the wrapped cause
`errors.Is(err, jwt.ErrTokenUnverifiable)` identifies the class; the wrapped error tells you whether it was a lookup miss or a fetch failure.
go if errors.Is(err, jwt.ErrTokenUnverifiable) { // The wrapped error is whatever your Keyfunc returned: log it, answer 401. log.Printf("cannot verify token: %v", errors.Unwrap(err)) }