jaegertracing/jaeger · error

failed to delete indices: %w

Error message

failed to delete indices: %w

What it means

This error is returned by IndicesClient.indexDeleteRequest (used by DeleteAllIndices and DeleteIndices) when the Elasticsearch DELETE request for one or more indices fails for a reason that is not a recognizable HTTP response error with a non-200 status. The underlying cause (network failure, transport error, serialization issue, or an unrecognized error type) is wrapped with %w so callers can errors.Is/As into it. If the server did return a structured ResponseError, a prefixMessage variant with the index list is returned instead.

Source

Thrown at internal/storage/elasticsearch/esclient/index_client.go:132

	// A zero master timeout is omitted so the cluster applies its own default
	// rather than master_timeout=0s, which asks the master to respond within no
	// time and can fail on a transient master delay.
	params := fmt.Sprintf("ignore_unavailable=%t", i.IgnoreUnavailableIndex)
	if i.MasterTimeoutSeconds > 0 {
		params = fmt.Sprintf("master_timeout=%ds&%s", i.MasterTimeoutSeconds, params)
	}
	_, err := i.request(ctx, elasticRequest{
		endpoint: concatIndices + "?" + params,
		method:   http.MethodDelete,
	})
	if err != nil {
		var responseError ResponseError
		if errors.As(err, &responseError) {
			if responseError.StatusCode != http.StatusOK {
				return responseError.prefixMessage("failed to delete indices: " + concatIndices)
			}
		}
		return fmt.Errorf("failed to delete indices: %w", err)
	}
	return nil
}

// DeleteIndices deletes specified set of indices.
func (i *IndicesClient) DeleteIndices(ctx context.Context, indices []Index) error {
	concatIndices := ""
	for j, index := range indices {
		// verify the length of the concatIndices
		// An HTTP line is should not be larger than 4096 bytes
		// a line contains other than concatIndices data in the request, ie: master_timeout
		// for a safer side check the line length should not exceed 4000
		if (len(concatIndices) + len(index.Index)) > 4000 {
			err := i.indexDeleteRequest(ctx, concatIndices)
			if err != nil {
				return err
			}
			concatIndices = ""

View on GitHub (pinned to 806f444784)

Solutions

  1. Verify Elasticsearch is reachable at the configured addresses (curl the cluster health endpoint) and fix the server address/TLS config
  2. Retry the delete once the cluster is back — index deletion is idempotent when ignore_unavailable=true
  3. Check context cancellation/deadline: increase the timeout on the context passed to DeleteIndices/DeleteAllIndices
  4. Inspect the wrapped cause with errors.Unwrap/errors.As to identify the transport-level failure

Example fix

// before
if err := indicesClient.DeleteAllIndices(ctx); err != nil {
    return fmt.Errorf("purge failed: %w", err) // opaque
}
// after
var respErr esclient.ResponseError
if err := indicesClient.DeleteAllIndices(ctx); err != nil {
    if errors.As(err, &respErr) {
        log.Printf("ES rejected delete, status=%d", respErr.StatusCode)
    } else {
        log.Printf("ES unreachable/transport failure: %v", err)
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: ES reachable?
resp, err := http.Get(esURL + "/_cluster/health")
if err != nil || resp.StatusCode != 200 {
    return fmt.Errorf("ES not reachable, skipping delete")
}

Type guard

var respErr esclient.ResponseError
isESRejection := errors.As(err, &respErr) // false => transport failure, retryable

Try / catch

if err := client.DeleteAllIndices(ctx); err != nil {
    var respErr esclient.ResponseError
    if errors.As(err, &respErr) {
        return fmt.Errorf("ES rejected delete (status %d): %w", respErr.StatusCode, err)
    }
    return retryWithBackoff(err) // transport failure
}

Prevention

When it happens

Trigger: DELETE <indices>?[master_timeout=..&]ignore_unavailable=.. fails without a parseable ResponseError: connection refused/timeout to ES, TLS handshake failure, context cancellation mid-request, or a non-JSON error body that cannot be wrapped as ResponseError.

Common situations: Elasticsearch is down or unreachable when Jaeger tries to purge/delete indices; DNS or port misconfiguration in the ES server addresses; firewall or proxy dropping DELETE requests; tests wiping indices (DeleteAllIndices) against a stopped container.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/070f7d62d6c1b701. Report an issue: GitHub.