{"record":{"id":"70278d0ea1cf7279","repo":"dgraph-io/dgraph","slug":"claims-in-jwt-token-is-not-map-claims-70278d","errorCode":null,"errorMessage":"claims in jwt token is not map claims","messagePattern":"claims in jwt token is not map claims","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/jwt_helper.go","lineNumber":50,"sourceCode":"\t\tif WorkerConfig.AclJwtAlg == nil {\n\t\t\treturn nil, errors.Errorf(\"ACL is disabled\")\n\t\t}\n\t\tif token.Method.Alg() != WorkerConfig.AclJwtAlg.Alg() {\n\t\t\treturn nil, errors.Errorf(\"unexpected signing method in token: %v\", token.Header[\"alg\"])\n\t\t}\n\t\treturn MaybeKeyToBytes(WorkerConfig.AclPublicKey), nil\n\t})\n\tif err != nil {\n\t\t// This is for backward compatibility in clients\n\t\tif errors.Is(err, jwt.ErrTokenExpired) {\n\t\t\terr = errors.Wrap(errTokenExpired, jwt.ErrTokenInvalidClaims.Error())\n\t\t}\n\t\treturn nil, errors.Wrapf(err, \"unable to parse jwt token\")\n\t}\n\n\tclaims, ok := token.Claims.(jwt.MapClaims)\n\tif !ok || !token.Valid {\n\t\treturn nil, errors.Errorf(\"claims in jwt token is not map claims\")\n\t}\n\treturn claims, nil\n}\n\nfunc ExtractUserName(jwtToken string) (string, error) {\n\tclaims, err := ParseJWT(jwtToken)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tuserId, ok := claims[\"userid\"].(string)\n\tif !ok {\n\t\treturn \"\", errors.Errorf(\"userid in claims is not a string:%v\", userId)\n\t}\n\n\treturn userId, nil\n}\n\nfunc ExtractNamespaceFromJwt(jwtToken string) (uint64, error) {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/x/jwt_helper.go#L32-L68","documentation":"After a successful jwt.Parse, ParseJWT asserts the parsed Claims to jwt.MapClaims and checks token.Valid. If the assertion fails or the token is otherwise invalid, this error is returned. In practice this happens when the token's claims type is unexpected (not a map of string->interface{}, e.g. a registered claims struct was encoded) or the parser reports the token invalid despite no error.","triggerScenarios":"token.Claims does not type-assert to jwt.MapClaims (token was created with a concrete claims struct like jwt.RegisteredClaims) or token.Valid is false after Parse returned no error.","commonSituations":"Tokens minted by another service using a custom Claims type rather than map claims; hand-edited tokens; a JWT library version mismatch changing claims decoding behavior; tampered tokens that fail validity checks.","solutions":["Re-issue the token with map-style claims (jwt.MapClaims / standard registered claims as a JSON object).","Verify which condition failed: decode the token payload and confirm claims is a JSON object, not an array or scalar.","Check the minting library/code path for a custom Claims struct; switch it to jwt.MapClaims.","If token.Valid is false with nil error, update/verify the golang-jwt/jwt v5 usage and validation options."],"exampleFix":"// before: mint with struct claims\ntok := jwt.NewWithClaims(alg, myCustomClaims{...})\n// after: mint with map claims\ntok := jwt.NewWithClaims(alg, jwt.MapClaims{\"userid\": \"u1\", \"namespace\": 0, \"exp\": time.Now().Add(time.Hour).Unix()})","handlingStrategy":"type-guard","validationCode":"// peek at payload before sending\nparts := strings.Split(token, \".\")\npayload, _ := base64.RawURLEncoding.DecodeString(parts[1])\nif !json.Valid(payload) || payload[0] != '{' {\n    return errors.New(\"jwt payload is not a JSON object of claims\")\n}","typeGuard":"func validMapClaims(token *jwt.Token) (jwt.MapClaims, bool) {\n    claims, ok := token.Claims.(jwt.MapClaims)\n    return claims, ok && token.Valid\n}","tryCatchPattern":"claims, err := x.ParseJWT(token)\nif err != nil {\n    if strings.Contains(err.Error(), \"claims in jwt token is not map claims\") {\n        // token was minted with non-map claims: re-issue with jwt.MapClaims\n    }\n    return err\n}","preventionTips":["Mint all tokens with jwt.MapClaims, not custom Claims structs.","Use the same golang-jwt/jwt (v5) library on minting and verifying sides.","Inspect tokens at jwt.io when integrating a new issuer.","Keep required claims (userid, namespace, exp) present as JSON object members."],"tags":["jwt","claims","validation","authentication"],"backgroundTag":"jwt-invalid-claims","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}