gofr-dev/gofr · critical
%w: creating index: %w
Error message
%w: creating index: %w
What it means
This is errOperation wrapped around the error from esapi.IndicesCreateRequest.Do in CreateIndex. It means the HTTP request to Elasticsearch never completed at the transport layer: connection refused, DNS failure, TLS error, timeout, or a cancelled context. No HTTP response was produced, unlike errResponse cases.
Source
Thrown at pkg/gofr/datasource/elasticsearch/elasticsearch.go:136
}
start := time.Now()
tracedCtx, span := c.addTrace(ctx, "create-index", []string{index}, "")
body, err := json.Marshal(settings)
if err != nil {
return fmt.Errorf("%w: settings: %w", errMarshaling, err)
}
req := esapi.IndicesCreateRequest{
Index: index,
Body: bytes.NewReader(body),
}
res, err := req.Do(tracedCtx, c.client)
if err != nil {
return fmt.Errorf("%w: creating index: %w", errOperation, err)
}
defer res.Body.Close()
if res.IsError() {
return fmt.Errorf("%w: %s", errResponse, res.String())
}
c.sendOperationStats(start, fmt.Sprintf("CREATE INDEX %s", index),
[]string{index}, "", settings, span)
return nil
}
func (c *Client) DeleteIndex(ctx context.Context, index string) error {
if strings.TrimSpace(index) == "" {
return errEmptyIndex
}
View on GitHub (pinned to 187eb24962)
Solutions
- Verify Config.Addresses points at a reachable ES HTTP endpoint (default port 9200).
- Check cluster/container health: curl the ES endpoint directly from the app host.
- Confirm Connect() succeeded and the health check passed at startup.
- Inspect the inner wrapped error for connection refused vs DNS vs timeout to target the fix.
- Ensure the passed context has sufficient deadline and is not already cancelled.
Example fix
// before err := client.CreateIndex(ctx, "orders", settings) // ctx already cancelled // after ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() err := client.CreateIndex(ctx, "orders", settings)
Defensive patterns
Strategy: retry
Validate before calling
// verify reachability before calling
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := client.HealthCheck(ctx); err != nil {
return fmt.Errorf("elasticsearch unreachable: %w", err)
} Try / catch
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
err := client.CreateIndex(ctx, index, settings)
cancel()
if err == nil {
break
}
lastErr = err
if strings.Contains(err.Error(), "elasticsearch operation error") {
time.Sleep(time.Duration(attempt+1) * time.Second) // transport error: retry
continue
}
return err // non-transport error: do not retry
}
return lastErr Prevention
- Verify Addresses and port (9200) in config for each environment.
- Call Connect()/HealthCheck at startup and fail fast with a clear message.
- Always pass contexts with adequate deadlines for index operations.
- Add readiness checks in docker-compose/k8s so the app starts after ES is up.
When it happens
Trigger: Calling CreateIndex when the ES cluster is unreachable: wrong Addresses in Config, cluster down, network/firewall blocking the port, client not yet connected (Connect() failed and c.client is effectively unusable), or the ctx passed in is already cancelled/expired.
Common situations: Developers hit this in dev environments where ES runs in Docker but the app uses localhost incorrectly, after a cluster restart, with wrong port (9200 vs 9300), during TLS misconfiguration, or when a short request context expires before the call finishes.
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: deleting index: %w
- %w: executing search: %w
- %w: executing bulk: %w
- failed to dial FTP server %q: %w
- connection error
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/d1ca41e156bd5778.
Report an issue: GitHub.