{"record":{"id":"5afba549184e91a1","repo":"ory/hydra","slug":"jwt-from-authorization-http-header-is-missing-valu","errorCode":null,"errorMessage":"jwt from authorization HTTP header is missing value for \"kid\" in token header","messagePattern":"jwt from authorization HTTP header is missing value for \"kid\" in token header","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"oryx/jwtmiddleware/middleware.go","lineNumber":104,"sourceCode":"\tc := &middlewareOptions{\n\t\tSigningMethod: jwt.SigningMethodES256,\n\t\tErrorWriter:   herodot.NewJSONWriter(nil),\n\t}\n\n\tfor _, o := range opts {\n\t\to(c)\n\t}\n\tjc := jwksx.NewFetcher(wellKnownURL)\n\treturn &Middleware{\n\t\to:   c,\n\t\twku: wellKnownURL,\n\t\tjm: jwtmiddleware.New(\n\t\t\tfunc(ctx context.Context, rawToken string) (any, error) {\n\t\t\t\treturn jwt.NewParser(\n\t\t\t\t\tjwt.WithValidMethods([]string{c.SigningMethod.Alg()}),\n\t\t\t\t).Parse(rawToken, func(token *jwt.Token) (interface{}, error) {\n\t\t\t\t\tif raw, ok := token.Header[\"kid\"]; !ok {\n\t\t\t\t\t\treturn nil, errors.New(`jwt from authorization HTTP header is missing value for \"kid\" in token header`)\n\t\t\t\t\t} else if kid, ok := raw.(string); !ok {\n\t\t\t\t\t\treturn nil, fmt.Errorf(`jwt from authorization HTTP header is expecting string value for \"kid\" in tokenWithoutKid header but got: %T`, raw)\n\t\t\t\t\t} else if k, err := jc.GetKey(kid); err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn k.Key, nil\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t},\n\t\t\tjwtmiddleware.WithCredentialsOptional(false),\n\t\t\tjwtmiddleware.WithTokenExtractor(func(r *http.Request) (string, error) {\n\t\t\t\t// wrapping the extractor to get a herodot.ErrorContainer\n\t\t\t\ttoken, err := jwtmiddleware.AuthHeaderTokenExtractor(r)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn \"\", herodot.ErrUnauthorized().WithReason(err.Error())\n\t\t\t\t}\n\t\t\t\treturn token, nil\n\t\t\t}),","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/jwtmiddleware/middleware.go#L86-L122","documentation":"This error comes from the custom jwtmiddleware KeyFunc wired into the JWT parser: after the token's signature algorithm is validated, the key extractor inspects the token header and requires a string \"kid\" claim. If the header has no \"kid\" (or it appears before the check), the keyfunc fails and the middleware rejects the request because it cannot select the verification key.","triggerScenarios":"A bearer token whose JWT header lacks the \"kid\" field is sent to an endpoint protected by this middleware (built with a signing method that requires kid-based key selection via jc.GetKey).","commonSituations":"Client SDKs or identity providers minting minimal headers without kid, tokens minted by a different service with a single static key, hand-crafted test tokens, an issuer upgrade that dropped kid from headers.","solutions":["Fix the token issuer to always include a string \"kid\" header matching a key published in the JWKS.","Re-mint the token with your signing library, adding `kid` to the header map.","If only one key exists server-side, adjust the keyfunc to fall back to that key when kid is absent instead of erroring.","Verify the client isn't stripping header fields through a proxy or token-exchange step."],"exampleFix":"// before (client minting token)\ntok := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) // header has no kid\n// after\ntok := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)\ntok.Header[\"kid\"] = \"my-signing-key-2024-01\"","handlingStrategy":"validation","validationCode":"// client side: check token header before sending\nparts := strings.Split(rawToken, \".\")\nhdr, _ := base64.RawURLEncoding.DecodeString(parts[0])\nvar h map[string]any\njson.Unmarshal(hdr, &h)\nif _, ok := h[\"kid\"].(string); !ok {\n\treturn fmt.Errorf(\"token header must include a string kid, got: %v\", h[\"kid\"])\n}","typeGuard":null,"tryCatchPattern":"// inside the middleware KeyFunc\nif raw, ok := token.Header[\"kid\"]; !ok {\n\treturn nil, errors.New(`jwt from authorization HTTP header is missing value for \"kid\" in token header`)\n} // caller: return 401 with a clear message so clients know to re-mint tokens with kid","preventionTips":["Always set the kid header when signing tokens, even with a single key","Add a contract test that decodes the token header and asserts kid presence","Document the kid requirement for any internal service minting tokens for this API","Log the decoded token header (never the token) on auth failures to speed up diagnosis"],"tags":["jwt","middleware","http-header"],"backgroundTag":"jwt-missing-kid-header","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}