{"record":{"id":"b9b30cb26dfafd47","repo":"dgraph-io/dgraph","slug":"kid-not-present-in-jwt","errorCode":null,"errorMessage":"kid not present in JWT","messagePattern":"kid not present in JWT","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphql/authorization/auth.go","lineNumber":359,"sourceCode":"// JWKUrl.\nfunc (a *AuthMeta) validateThroughJWKUrl(jwtStr string) (*jwt.Token, error) {\n\tvar err error\n\tvar token *jwt.Token\n\tfor i := range a.JWKUrls {\n\t\tif a.isExpired(i) {\n\t\t\terr = a.refreshJWK(i)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrap(err, \"while refreshing JWK from the URL\")\n\t\t\t}\n\t\t}\n\n\t\ttoken, err = jwt.ParseWithClaims(\n\t\t\tjwtStr,\n\t\t\t&CustomClaims{authMeta: a},\n\t\t\tfunc(token *jwt.Token) (interface{}, error) {\n\t\t\t\tkid := token.Header[\"kid\"]\n\t\t\t\tif kid == nil {\n\t\t\t\t\treturn nil, errors.Errorf(\"kid not present in JWT\")\n\t\t\t\t}\n\n\t\t\t\tsigningKeys := a.jwkSet[i].Key(kid.(string))\n\t\t\t\tif len(signingKeys) == 0 {\n\t\t\t\t\treturn nil, errors.Errorf(\"Invalid kid\")\n\t\t\t\t}\n\t\t\t\treturn signingKeys[0].Key, nil\n\t\t\t},\n\t\t)\n\n\t\tif err == nil {\n\t\t\treturn token, nil\n\t\t}\n\t}\n\treturn nil, err\n}\n\nfunc (a *AuthMeta) validateJWTCustomClaims(jwtStr string) (*CustomClaims, error) {","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/graphql/authorization/auth.go#L341-L377","documentation":"The JWT key-lookup callback runs for every token parsed against a JWK URL set. It requires a `kid` (key ID) header so it can select the correct public key from the fetched JWK set. If the token's header has no `kid`, the library cannot pick a key and rejects the token with this message. It is surfaced to the caller wrapped as \"unable to parse jwt token:...\".","triggerScenarios":"jwt.ParseWithClaims invokes the keyfunc; token.Header[\"kid\"] is nil because the JWT issuer signed the token without embedding a kid header, or the token is malformed/手工 crafted.","commonSituations":"Using an IdP or token signer configured to omit kid (common with single-key HS256 signers); token produced by an older service or library version that omits kid; testing with hand-rolled tokens; wrong endpoint issuing tokens from a different signer configuration.","solutions":["Fix the token issuer so it includes a kid header matching an entry in the JWK set.","If only one key is used, consider static-key verification (set Algo + VerificationKey instead of JWKUrls).","Verify you are validating tokens from the correct issuer/environment.","Decode the token header (base64 of the first dot-separated segment) to confirm kid is truly missing.","Pin/upgrade the signing library at the issuer to one that sets kid."],"exampleFix":"// issuer side: before\ntoken := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)\n// after\ntoken := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)\ntoken.Header[\"kid\"] = \"my-key-id-2024\"","handlingStrategy":"validation","validationCode":"func tokenHasKid(jwtStr string) bool {\n    parts := strings.Split(jwtStr, \".\")\n    if len(parts) != 3 { return false }\n    hdr, err := base64.RawURLEncoding.DecodeString(parts[0])\n    if err != nil { return false }\n    var h map[string]interface{}\n    if json.Unmarshal(hdr, &h) != nil { return false }\n    _, ok := h[\"kid\"].(string)\n    return ok\n}","typeGuard":"func hasString(v map[string]interface{}, key string) (string, bool) {\n    s, ok := v[key].(string)\n    return s, ok && s != \"\"\n}","tryCatchPattern":"if _, err := auth.ExtractCustomClaims(ctx, jwtStr); err != nil && strings.Contains(err.Error(), \"kid not present\") {\n    return nil, status.Error(codes.Unauthenticated, \"token missing kid header; obtain a token from a compliant issuer\")\n}","preventionTips":["Ensure your IdP/signer always includes kid in the token header","Validate token headers in CI with a sample token from your issuer","Reject non-kid tokens early at the gateway with a clear message","Document the kid requirement for internal token issuers"],"tags":["jwt","jwk","kid","authentication"],"backgroundTag":"jwt-missing-kid-header","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}