jaegertracing/jaeger · error
failed to create index: %w
Error message
failed to create index: %w
What it means
Returned by IndicesClient.CreateIndex when the HTTP PUT that creates an index fails with an error that is not a structured ResponseError (e.g. a transport-level failure). The wrapped err is the real cause. When ES does answer with a structured non-200 response, the ResponseError.prefixMessage variant naming the index is returned instead.
Source
Thrown at internal/storage/elasticsearch/esclient/index_client.go:177
}
}
return nil
}
// CreateIndex an ES index
func (i *IndicesClient) CreateIndex(ctx context.Context, index string) error {
_, err := i.request(ctx, elasticRequest{
endpoint: index,
method: http.MethodPut,
})
if err != nil {
var responseError ResponseError
if errors.As(err, &responseError) {
if responseError.StatusCode != http.StatusOK {
return responseError.prefixMessage("failed to create index: " + index)
}
}
return fmt.Errorf("failed to create index: %w", err)
}
return nil
}
// CreateAlias an ES specific set of index aliases
func (i *IndicesClient) CreateAlias(ctx context.Context, aliases []Alias) error {
err := i.aliasAction(ctx, "add", aliases)
if err != nil {
var responseError ResponseError
if errors.As(err, &responseError) {
if responseError.StatusCode != http.StatusOK {
return responseError.prefixMessage("failed to create aliases: " + i.aliasesString(aliases))
}
}
return fmt.Errorf("failed to create aliases: %w", err)
}
return nil
}View on GitHub (pinned to 806f444784)
Solutions
- Check ES connectivity (curl /_cluster/health) and fix address/credentials in the storage config
- Retry CreateIndex — ES returns 400 resource_already_exists_exception if it actually succeeded, so a re-run after a transient failure is safe
- Increase the client/request timeout if the cluster was slow to elect a master
- Unwrap the error (errors.Is/As on the %w chain) to find the underlying transport cause
Example fix
// before
if err := client.CreateIndex(ctx, "jaeger-span-000001"); err != nil {
return err // transport failure indistinguishable from ES rejection
}
// after
if err := client.CreateIndex(ctx, "jaeger-span-000001"); err != nil {
var respErr esclient.ResponseError
if !errors.As(err, &respErr) {
// transport-level failure: safe to retry
return retryable(err)
}
return err
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: cluster health
resp, err := http.Get(esURL + "/_cluster/health?wait_for_status=yellow&timeout=5s")
if err != nil || resp.StatusCode != 200 {
return fmt.Errorf("ES unavailable, deferring CreateIndex")
} Type guard
var respErr esclient.ResponseError
isTransportFailure := func(err error) bool {
var re esclient.ResponseError
return !errors.As(err, &re) // no structured ES response => retryable
} Try / catch
if err := client.CreateIndex(ctx, index); err != nil {
var respErr esclient.ResponseError
if errors.As(err, &respErr) {
return fmt.Errorf("ES rejected create (status %d): %w", respErr.StatusCode, err)
}
return retryWithBackoff(err) // CreateIndex is idempotent (already-exists => 400)
} Prevention
- Run CreateIndex only after cluster health is green/yellow
- Treat 'already exists' responses as success to make bootstrap re-runnable
- Keep ES address/TLS config validated at startup, not at first use
When it happens
Trigger: PUT /<index> fails without a parseable ResponseError: network outage, connection reset, TLS error, or request context canceled before a response arrives.
Common situations: ES node down or restarting during Jaeger index initialization; wrong port/scheme in ES config; security proxy terminating the connection; short client timeout during cluster startup.
Related errors
- failed to resolve backend version: %w
- failed to delete indices: %w
- failed to create aliases: %w
- failed to delete aliases: %w
- failed to check if index exists: %w
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/e6f89422facdfa71.
Report an issue: GitHub.