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

  1. Point JWTClaimPath at the first element ("roles[0]") if any single role suffices, or at a claim guaranteed present for all users.
  2. Ensure the identity provider always includes at least one role (e.g. a default role) in every issued token.
  3. Prefer a non-array claim (a flat role string) when your authorization model allows one role per user.
  4. 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

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


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/9add33de8633343c. Report an issue: GitHub.