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.Client

View on GitHub (pinned to 187eb24962)

Solutions

  1. Set the index within bounds of the actual array (usually "roles[0]")
  2. Prefer a stable claim structure (nested object or first-element convention guaranteed by the issuer) instead of hard-coded high indices
  3. 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

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


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