gofr-dev/gofr · error
elasticsearch health check failed
Error message
elasticsearch health check failed
What it means
The claim is an array but the parsed index is negative or >= len(arr), so the library wraps errArrayIndexOutOfBounds with the index and the array length. Note the error message uses %d for index (with length in parens), produced only in this bounds check inside extractArrayClaim.
Source
Thrown at pkg/gofr/datasource/elasticsearch/elasticsearch.go:29
es "github.com/elastic/go-elasticsearch/v8"
"github.com/elastic/go-elasticsearch/v8/esapi"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
const (
statusDown = "DOWN"
statusUp = "UP"
defaultTimeout = 5 * time.Second
)
var (
errEmptyIndex = errors.New("index name cannot be empty")
errEmptyDocumentID = errors.New("document ID cannot be empty")
errEmptyQuery = errors.New("query cannot be empty")
errEmptyOperations = errors.New("operations cannot be empty")
errHealthCheckFailed = errors.New("elasticsearch health check failed")
errOperation = errors.New("elasticsearch operation error")
errMarshaling = errors.New("error marshaling data")
errParsingResponse = errors.New("error parsing response")
errResponse = errors.New("invalid elasticsearch response")
errEncodingOperation = errors.New("error encoding operation")
)
// Config holds the configuration for connecting to Elasticsearch.
type Config struct {
Addresses []string
Username string
Password string
}
// Client represents the Elasticsearch client.
type Client struct {
config Config
client *es.ClientView on GitHub (pinned to 187eb24962)
Solutions
- Set the index within bounds of the actual array (usually "roles[0]")
- Prefer a stable claim structure (nested object or first-element convention guaranteed by the issuer) instead of hard-coded high indices
- Defensively: after extraction, compare with the array length or errors.Is(err, errArrayIndexOutOfBounds) and fall back to default role
Example fix
// before extractClaimValue(claims, "roles[3]") // roles has 1 element // after extractClaimValue(claims, "roles[0]")
Defensive patterns
Strategy: try-catch
Validate before calling
if arr, ok := claims["roles"].([]any); !ok || len(arr) <= idx {
return fmt.Errorf("roles index %d out of range (len=%d)", idx, len(arr))
} Type guard
func indexInBounds(claims jwt.MapClaims, key string, idx int) bool {
arr, ok := claims[key].([]any)
return ok && idx >= 0 && idx < len(arr)
} Try / catch
v, err := extractClaimValue(claims, "roles[0]")
if errors.Is(err, errArrayIndexOutOfBounds) {
// assign default role or reject with 403
} Prevention
- Prefer index [0] or an issuer-guaranteed structure over hard-coded deep indices
- Reject tokens with empty role arrays at validation time
- Handle users with fewer roles than the config assumes (empty-array policy)
When it happens
Trigger: "roles[3]" when the token's roles array has 1–3 elements; config written against a richer token (multiple roles) being used with tokens carrying a single role; an index parsed from a negative or out-of-range value.
Common situations: Hard-coded indices in RBAC config that don't match IdP output; users with zero or one roles while the path assumes more; A/B issuers emitting arrays of different sizes.
Related errors
- %w: deleting document: %w
- %w: %s
- index name cannot be empty
- document ID cannot be empty
- query cannot be empty
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/bb6a131d95f9453b.
Report an issue: GitHub.