{"record":{"id":"cd0d20a4b2d00684","repo":"hashicorp/nomad","slug":"errnokeyid","errorCode":"ErrNoKeyID","errorMessage":"missing key ID header","messagePattern":"missing key ID header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/joseutil/joseutil.go","lineNumber":12,"sourceCode":"// Copyright IBM Corp. 2015, 2026\n// SPDX-License-Identifier: BUSL-1.1\n\npackage joseutil\n\nimport (\n\t\"errors\"\n\n\t\"github.com/go-jose/go-jose/v3/jwt\"\n)\n\nvar ErrNoKeyID = errors.New(\"missing key ID header\")\n\n// KeyID returns the KeyID header for a JWT or ErrNoKeyID if a key id could not\n// be found. No clue why jose makes this so awkward.\nfunc KeyID(token *jwt.JSONWebToken) (string, error) {\n\tfor _, h := range token.Headers {\n\t\tif h.KeyID != \"\" {\n\t\t\treturn h.KeyID, nil\n\t\t}\n\t}\n\treturn \"\", ErrNoKeyID\n}\n","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/joseutil/joseutil.go#L1-L24","documentation":"ErrNoKeyID is a sentinel error returned by joseutil.KeyID when a parsed JWT has no `kid` (key ID) JOSE header. Vault uses the kid to look up which verification key to use, so a token without one cannot be processed.","triggerScenarios":"Calling joseutil.KeyID(token *jwt.JSONWebToken) on a token whose headers contain no non-empty KeyID field — i.e. a JWT signed/published without the kid header.","commonSituations":"OIDC providers or JWKS endpoints that omit the kid header; hand-crafted JWTs in integration tests; tokens minted by libraries that don't set kid when a single key is in use.","solutions":["Re-issue the JWT ensuring the signing library sets the `kid` header (e.g. jose.SignerOption with jose.Header(\"kid\", keyID)).","If you control the flow, treat ErrNoKeyID explicitly with errors.Is and fall back to single-key verification or reject the token early with a clear client-side message.","Check the identity provider configuration to ensure key rotation includes kid in the JWKS."],"exampleFix":"// before\nkid, err := joseutil.KeyID(token) // ErrNoKeyID\n// after\nkid, err := joseutil.KeyID(token)\nif errors.Is(err, joseutil.ErrNoKeyID) {\n    return fmt.Errorf(\"token lacks kid header; configure the issuer to include it\")\n}","handlingStrategy":"try-catch","validationCode":"// no pre-call validation possible; inspect headers yourself if desired\nfunc hasKid(token *jwt.JSONWebToken) bool {\n    for _, h := range token.Headers {\n        if h.KeyID != \"\" { return true }\n    }\n    return false\n}","typeGuard":"func tokenHasKeyID(headers []jose.Header) bool {\n    for _, h := range headers {\n        if h.KeyID != \"\" { return true }\n    }\n    return false\n}","tryCatchPattern":"kid, err := joseutil.KeyID(token)\nif errors.Is(err, joseutil.ErrNoKeyID) {\n    // reject token or fall back to single-key verification\n    return nil, fmt.Errorf(\"JWT missing kid header\")\n}","preventionTips":["Configure JWT issuers/signing libraries to always include the kid header.","Check the JWKS endpoints you consume publish kid per key.","Use errors.Is(err, joseutil.ErrNoKeyID) rather than string comparison."],"tags":["jwt","jose","authentication"],"backgroundTag":"jwt-missing-kid-header","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}