{"record":{"id":"91a3eb5feb169678","repo":"gofr-dev/gofr","slug":"claim-key-not-found","errorCode":null,"errorMessage":"claim key not found","messagePattern":"claim key not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/rbac/middleware.go","lineNumber":65,"sourceCode":"\tErrRoleNotFound = errors.New(\"unauthorized: role not found\")\n\n\t// errJWTClaimsNotFound is returned when JWT claims are not found in request context.\n\terrJWTClaimsNotFound = errors.New(\"JWT claims not found in request context\")\n\n\t// errEmptyClaimPath is returned when claim path is empty.\n\terrEmptyClaimPath = errors.New(\"empty claim path\")\n\n\t// errClaimPathNotFound is returned when a claim path is not found in JWT claims.\n\terrClaimPathNotFound = errors.New(\"claim path not found\")\n\n\t// errInvalidArrayNotation is returned when array notation is invalid.\n\terrInvalidArrayNotation = errors.New(\"invalid array notation\")\n\n\t// errInvalidArrayIndex is returned when array index is invalid.\n\terrInvalidArrayIndex = errors.New(\"invalid array index\")\n\n\t// errClaimKeyNotFound is returned when a claim key is not found.\n\terrClaimKeyNotFound = errors.New(\"claim key not found\")\n\n\t// errClaimValueNotArray is returned when a claim value is not an array.\n\terrClaimValueNotArray = errors.New(\"claim value is not an array\")\n\n\t// errArrayIndexOutOfBounds is returned when array index is out of bounds.\n\terrArrayIndexOutOfBounds = errors.New(\"array index out of bounds\")\n\n\t// errInvalidClaimStructure is returned when claim structure is invalid.\n\terrInvalidClaimStructure = errors.New(\"invalid claim structure\")\n\n\t// errAuthorizationError is returned as a generic error message for unknown errors in traces.\n\terrAuthorizationError = errors.New(\"authorization error\")\n)\n\n// Middleware creates an HTTP middleware function that enforces RBAC authorization.\n// It extracts the user's role and checks if the role is allowed for the requested route.\n//\n//nolint:gocognit,gocyclo // Middleware complexity is acceptable due to multiple authorization paths","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/rbac/middleware.go#L47-L83","documentation":"errClaimKeyNotFound is returned by extractArrayClaim when the key preceding the bracket notation (e.g. \"roles\" in \"roles[0]\") does not exist in the JWT claims map. It means the token's claims simply do not contain the named key that the array-notation path points at. Callers see it wrapped as \"failed to extract role from JWT: claim key not found: <key>\".","triggerScenarios":"JWTClaimPath like \"roles[0]\" while the incoming token's claims have no \"roles\" key at all — e.g. token issued without the roles claim, wrong issuer/realm, or path pointing at a renamed claim; the claims map lookup claims[key] fails with ok=false.","commonSituations":"Identity provider (Keycloak, Auth0, etc.) configured without the role claim in token mappers; after rotating to a new client whose token template dropped the claim; mismatch between configured path and actual claim names; testing with hand-crafted tokens missing claims.","solutions":["Decode the actual token (e.g. jwt.io) and confirm the key used in JWTClaimPath exists in the claims payload.","Update Config.JWTClaimPath to match the real claim name emitted by your identity provider.","Add/restore the claim in the identity provider's token mapper/client configuration so tokens include it.","Verify requests are hitting the intended issuer/realm — a different realm may omit the claim."],"exampleFix":"// before (token has \"groups\", config expects \"roles\")\nconfig.JWTClaimPath = \"roles[0]\"\n// after\nconfig.JWTClaimPath = \"groups[0]\"","handlingStrategy":"validation","validationCode":"func tokenHasClaim(claims jwt.MapClaims, key string) bool {\n    _, ok := claims[key]\n    return ok\n}\n// before relying on the middleware, decode a sample token and assert:\n// if !tokenHasClaim(sampleClaims, \"roles\") { log.Fatal(\"IdP token missing 'roles' claim\") }","typeGuard":"func claimPresent(claims jwt.MapClaims, key string) bool {\n    v, ok := claims[key]\n    return ok && v != nil\n}","tryCatchPattern":"if err := nextErr; err != nil && strings.Contains(err.Error(), \"claim key not found\") {\n    logger.Warn(\"token missing configured role claim — check IdP token mappers\", \"err\", err)\n    http.Error(w, \"unauthorized\", http.StatusUnauthorized)\n    return\n}","preventionTips":["Decode a token from each environment (jwt.io) and confirm claim names before configuring JWTClaimPath","Pin role claims in the IdP client/token mapper config so they are always emitted","Add an integration test that authenticates a real token through the RBAC middleware"],"tags":["go","jwt","rbac","claims"],"backgroundTag":"jwt-claim-not-found","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}