{"record":{"id":"bb6a131d95f9453b","repo":"gofr-dev/gofr","slug":"elasticsearch-health-check-failed","errorCode":null,"errorMessage":"elasticsearch health check failed","messagePattern":"elasticsearch health check failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/datasource/elasticsearch/elasticsearch.go","lineNumber":29,"sourceCode":"\n\tes \"github.com/elastic/go-elasticsearch/v8\"\n\t\"github.com/elastic/go-elasticsearch/v8/esapi\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nconst (\n\tstatusDown     = \"DOWN\"\n\tstatusUp       = \"UP\"\n\tdefaultTimeout = 5 * time.Second\n)\n\nvar (\n\terrEmptyIndex        = errors.New(\"index name cannot be empty\")\n\terrEmptyDocumentID   = errors.New(\"document ID cannot be empty\")\n\terrEmptyQuery        = errors.New(\"query cannot be empty\")\n\terrEmptyOperations   = errors.New(\"operations cannot be empty\")\n\terrHealthCheckFailed = errors.New(\"elasticsearch health check failed\")\n\terrOperation         = errors.New(\"elasticsearch operation error\")\n\terrMarshaling        = errors.New(\"error marshaling data\")\n\terrParsingResponse   = errors.New(\"error parsing response\")\n\terrResponse          = errors.New(\"invalid elasticsearch response\")\n\terrEncodingOperation = errors.New(\"error encoding operation\")\n)\n\n// Config holds the configuration for connecting to Elasticsearch.\ntype Config struct {\n\tAddresses []string\n\tUsername  string\n\tPassword  string\n}\n\n// Client represents the Elasticsearch client.\ntype Client struct {\n\tconfig  Config\n\tclient  *es.Client","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/elasticsearch/elasticsearch.go#L11-L47","documentation":"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.","triggerScenarios":"\"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.","commonSituations":"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.","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"],"exampleFix":"// before\nextractClaimValue(claims, \"roles[3]\") // roles has 1 element\n// after\nextractClaimValue(claims, \"roles[0]\")","handlingStrategy":"try-catch","validationCode":"if arr, ok := claims[\"roles\"].([]any); !ok || len(arr) <= idx {\n    return fmt.Errorf(\"roles index %d out of range (len=%d)\", idx, len(arr))\n}","typeGuard":"func indexInBounds(claims jwt.MapClaims, key string, idx int) bool {\n    arr, ok := claims[key].([]any)\n    return ok && idx >= 0 && idx < len(arr)\n}","tryCatchPattern":"v, err := extractClaimValue(claims, \"roles[0]\")\nif errors.Is(err, errArrayIndexOutOfBounds) {\n    // assign default role or reject with 403\n}","preventionTips":["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)"],"tags":["jwt","rbac","index-out-of-range"],"backgroundTag":"array-index-out-of-bounds","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}