gofr-dev/gofr · critical
%w: executing search: %w
Error message
%w: executing search: %w
What it means
This is errOperation wrapped around the transport error from esapi.SearchRequest.Do. The search request failed before an HTTP response was produced: unreachable cluster, connection reset, TLS failure, or context deadline exceeded. The inner wrapped error distinguishes the transport cause.
Source
Thrown at pkg/gofr/datasource/elasticsearch/elasticsearch.go:206
}
start := time.Now()
tracedCtx, span := c.addTrace(ctx, "search", indices, "")
body, err := json.Marshal(query)
if err != nil {
return nil, fmt.Errorf("%w: query: %w", errMarshaling, err)
}
req := esapi.SearchRequest{
Index: indices,
Body: bytes.NewReader(body),
}
res, err := req.Do(tracedCtx, c.client)
if err != nil {
return nil, fmt.Errorf("%w: executing search: %w", errOperation, err)
}
defer res.Body.Close()
if res.IsError() {
return nil, fmt.Errorf("%w: %s", errResponse, res.String())
}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("%w: %w", errParsingResponse, err)
}
c.sendOperationStats(start, "SEARCH", indices, "", query, span)
return result, nil
}
View on GitHub (pinned to 187eb24962)
Solutions
- Check cluster reachability (curl the endpoint) and Config.Addresses correctness.
- Inspect the inner wrapped error: connection refused vs timeout vs TLS to target the fix.
- Increase the context deadline or optimize the query (fewer fields, pagination, aggregations tuning) if timing out.
- Add retry-with-backoff for transient connection resets.
- Verify startup Connect()/HealthCheck succeeded before issuing searches.
Example fix
// before
res, err := client.Search(ctx, []string{"orders"}, bigAggregationQuery) // context deadline exceeded
// after
qctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
res, err := client.Search(qctx, []string{"orders"}, optimizedQuery) Defensive patterns
Strategy: retry
Validate before calling
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := client.HealthCheck(ctx); err != nil {
return nil, fmt.Errorf("elasticsearch unavailable: %w", err)
} Try / catch
var result map[string]any
var err error
for attempt := 0; attempt < 3; attempt++ {
qctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
result, err = client.Search(qctx, indices, query)
cancel()
if err == nil {
break
}
if strings.Contains(err.Error(), "executing search") { // transport-level
time.Sleep(backoff(attempt))
continue
}
break // non-transport errors are not retryable
} Prevention
- Size context deadlines to your slowest query; profile expensive aggregations.
- Add retry with exponential backoff for transient connection resets.
- Verify DNS/service names in containerized environments (k8s service vs pod).
- Check HealthCheck at startup and on a monitor loop to detect outages early.
When it happens
Trigger: Calling Search when the ES cluster is unreachable or down, DNS fails, the port is wrong, Connect() never succeeded, the context times out before the query completes (common with expensive queries), or a load balancer drops the connection.
Common situations: Developers hit this in production when ES is restarted or under load and expensive queries exceed context deadlines, in k8s when service DNS/name is wrong, or in tests where the ES container isn't ready.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- %w: creating index: %w
- %w: deleting index: %w
- %w: query: %w
- %w: executing bulk: %w
- failed to dial FTP server %q: %w
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/a59e44d73ac3f37f.
Report an issue: GitHub.