gofr-dev/gofr · error
array index out of bounds
Error message
array index out of bounds
What it means
errArrayIndexOutOfBounds is returned by extractArrayClaim when the index in the claim path is a valid integer but exceeds the bounds of the actual array in the JWT claims (index < 0 or index >= len(arr)). The error message includes the requested index and the array length, e.g. "array index out of bounds: 2 (length: 1)". It means the configured path assumes more elements than the token carries.
Source
Thrown at pkg/gofr/rbac/middleware.go:71
errEmptyClaimPath = errors.New("empty claim path")
// errClaimPathNotFound is returned when a claim path is not found in JWT claims.
errClaimPathNotFound = errors.New("claim path not found")
// errInvalidArrayNotation is returned when array notation is invalid.
errInvalidArrayNotation = errors.New("invalid array notation")
// errInvalidArrayIndex is returned when array index is invalid.
errInvalidArrayIndex = errors.New("invalid array index")
// errClaimKeyNotFound is returned when a claim key is not found.
errClaimKeyNotFound = errors.New("claim key not found")
// errClaimValueNotArray is returned when a claim value is not an array.
errClaimValueNotArray = errors.New("claim value is not an array")
// errArrayIndexOutOfBounds is returned when array index is out of bounds.
errArrayIndexOutOfBounds = errors.New("array index out of bounds")
// errInvalidClaimStructure is returned when claim structure is invalid.
errInvalidClaimStructure = errors.New("invalid claim structure")
// errAuthorizationError is returned as a generic error message for unknown errors in traces.
errAuthorizationError = errors.New("authorization error")
)
// Middleware creates an HTTP middleware function that enforces RBAC authorization.
// It extracts the user's role and checks if the role is allowed for the requested route.
//
//nolint:gocognit,gocyclo // Middleware complexity is acceptable due to multiple authorization paths
func Middleware(config *Config) func(handler http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// If config is nil, allow all requests (fail open)
if config == nil {
handler.ServeHTTP(w, r)View on GitHub (pinned to 187eb24962)
Solutions
- Point JWTClaimPath at the first element ("roles[0]") if any single role suffices, or at a claim guaranteed present for all users.
- Ensure the identity provider always includes at least one role (e.g. a default role) in every issued token.
- Prefer a non-array claim (a flat role string) when your authorization model allows one role per user.
- If role sets vary per user, use a custom ErrorHandler to return a clear 401/403 message when the expected index is missing.
Example fix
// before (only one role is ever assigned) config.JWTClaimPath = "roles[1]" // after config.JWTClaimPath = "roles[0]"
Defensive patterns
Strategy: validation
Validate before calling
func indexInBounds(claims jwt.MapClaims, key string, idx int) bool {
arr, ok := claims[key].([]any)
return ok && idx >= 0 && idx < len(arr)
}
// sample-token check at startup:
// if !indexInBounds(sampleClaims, "roles", 0) { log.Fatal("roles array empty or missing") } Type guard
func safeRole(claims jwt.MapClaims, key string, idx int) (string, bool) {
arr, ok := claims[key].([]any)
if !ok || idx < 0 || idx >= len(arr) { return "", false }
s, ok := arr[idx].(string)
return s, ok
} Try / catch
if err != nil && strings.Contains(err.Error(), "array index out of bounds") {
logger.Warn("user token has fewer roles than the configured index", "err", err)
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
} Prevention
- Prefer index 0 or a non-array claim over hardcoded higher indexes
- Require the IdP to assign at least one (default) role to every user
- Test RBAC with tokens from the least-privileged users, not just admins
When it happens
Trigger: JWTClaimPath "roles[1]" or "roles[2]" while the token's "roles" array contains fewer elements (e.g. a user with a single role); any negative index like "roles[-1]"; users whose role list is empty hit this even when other users work fine.
Common situations: Hardcoding an index that is valid for admins but not for regular users; a Keycloak/IdP change that reduces the roles a client receives; per-tenant token differences where some tenants assign zero roles; load-balancing across realms with different role mappings.
Related errors
- claim key not found
- claim value is not an array
- invalid claim structure
- failed to extract role from JWT: %w
- %w: %s
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/9add33de8633343c.
Report an issue: GitHub.