gofr-dev/gofr · error

invalid elasticsearch response

Error message

invalid elasticsearch response

What it means

errResponse ("invalid elasticsearch response") is the sentinel error wrapped when the Elasticsearch HTTP response itself indicates an error. The client sends the request successfully, the server answers, but res.IsError() reports a 4xx/5xx status. The full raw ES response (status line and error body) is embedded via res.String(), so the underlying cause (bad query DSL, missing index, auth failure, mapping conflict) is visible in the wrapped message.

Source

Thrown at pkg/gofr/datasource/elasticsearch/elasticsearch.go:33

	"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
	logger  Logger
	metrics Metrics
	tracer  trace.Tracer
}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Read the res.String() payload in the wrapped error to get the exact ES error type and reason (e.g. index_not_found_exception vs parsing_exception).
  2. If index_not_found_exception, create the index first (call CreateIndex) or verify the index name spelling/environment.
  3. If parsing_exception or a DSL version issue, validate the query/settings JSON against the ES version's documentation.
  4. If 401/403, fix Config.Username/Password or the user's index-level permissions.
  5. If resource_already_exists_exception on CreateIndex, treat as idempotent: check index existence before creating.

Example fix

// before
if err := client.CreateIndex(ctx, "orders", settings); err != nil {
    return err // invalid elasticsearch response: [ES response with resource_already_exists_exception]
}
// after
if err := client.CreateIndex(ctx, "orders", settings); err != nil {
    if strings.Contains(err.Error(), "resource_already_exists_exception") {
        return nil // index already exists - safe to proceed
    }
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling the API, validate arguments the cluster would reject
if strings.TrimSpace(index) == "" { return errors.New("index required") }
// confirm the index exists to avoid index_not_found:
// GET /_cat/indices/<index> via HealthCheck or a HEAD request

Type guard

func IsESResponseError(err error) bool {
    return errors.Is(err, errResponseSentinel) || strings.Contains(err.Error(), "invalid elasticsearch response")
}

func ESExceptionIs(err error, exception string) bool {
    return IsESResponseError(err) && strings.Contains(err.Error(), exception)
}

Try / catch

if err := client.GetDocument(ctx, index, id); err != nil {
    switch {
    case strings.Contains(err.Error(), "index_not_found_exception"):
        // create index or fix name
    case strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "403"):
        // fix credentials/permissions
    default:
        return fmt.Errorf("elasticsearch get failed: %w", err)
    }
}

Prevention

When it happens

Trigger: Any call to IndexDocument, GetDocument, UpdateDocument, DeleteDocument, CreateIndex, or DeleteIndex where the ES cluster returns an HTTP error status: e.g. CreateIndex on an index that already exists (resource_already_exists_exception), Search/GetDocument on a nonexistent index (index_not_found_exception), UpdateDocument/DeleteDocument on a missing document, invalid query DSL (parsing_exception), or 401/403 from bad credentials.

Common situations: Developers hit this when an index was never created (or a migration didn't run), when the query body has invalid Elasticsearch DSL for the cluster's version (e.g. newer DSL on an older cluster), when credentials lack write permissions, or when the document ID typed in code doesn't exist.

Related errors


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