jaegertracing/jaeger · error
nil search response
Error message
nil search response
What it means
This error is raised by aggregationKeys in service_operation.go when the Elasticsearch SearchResponse pointer itself is nil. A nil response cannot carry any aggregation data, so the function fails fast; in contrast, a non-nil response with no Aggregations section yields an empty slice rather than an error.
Source
Thrown at internal/storage/v2/elasticsearch/tracestore/core/service_operation.go:181
resp, err := s.searcher.Search(ctx, indices, esclient.SearchRequest{
Size: 0,
Query: query.NewTermQuery(serviceName, service),
Aggregations: map[string]query.Aggregation{
operationsAggregation: query.NewTermsAggregation(operationNameField).Size(maxDocCount),
},
})
if err != nil {
return nil, fmt.Errorf("search operations failed: %w", err)
}
return aggregationKeys(resp, operationsAggregation)
}
// aggregationKeys extracts the bucket keys of a named terms aggregation. A
// response with no aggregations yields an empty slice; a response missing the
// requested aggregation is an error.
func aggregationKeys(resp *esclient.SearchResponse, name string) ([]string, error) {
if resp == nil {
return nil, errors.New("nil search response")
}
if resp.Aggregations == nil {
return []string{}, nil
}
agg, ok := resp.Aggregations.Terms(name)
if !ok {
return nil, errors.New("could not find aggregation of " + name)
}
keys := make([]string, 0, len(agg.Buckets))
for _, bucket := range agg.Buckets {
keys = append(keys, bucket.Key)
}
return keys, nil
}
func hashCode(s dbmodel.Service) string {
h := fnv.New64a()
h.Write([]byte(s.ServiceName))View on GitHub (pinned to 806f444784)
Solutions
- Ensure the searcher/client always returns either a valid response or a non-nil error, and check errors before using the response.
- Fix mock implementations used in tests to return a non-nil SearchResponse or an error.
- If a nil response with nil error is reproducible, report/investigate the underlying client call for transport failures.
Example fix
// before
resp, err := searcher.Search(ctx, req)
keys, err := aggregationKeys(resp, aggName) // panics/nils if resp==nil and err==nil
// after
resp, err := searcher.Search(ctx, req)
if err != nil || resp == nil { return err }
keys, err := aggregationKeys(resp, aggName) Defensive patterns
Strategy: type-guard
Validate before calling
if resp == nil {
return fmt.Errorf("searcher returned nil response")
} Type guard
func validResponse(r *esclient.SearchResponse) bool { return r != nil } Try / catch
keys, err := aggregationKeys(resp, name)
if err != nil && err.Error() == "nil search response" {
// treat as upstream client/transport failure; retry or surface 502
} Prevention
- Always check the searcher's error before touching the response pointer.
- Make mocks/tests return either (response, nil) or (nil, err), never (nil, nil).
- Wrap client calls so a nil response with nil error is impossible.
When it happens
Trigger: getServices or getOperations receiving a nil *SearchResponse from the searcher — typically when the underlying ES client transport fails in a way that yields a nil response alongside an error, or a test/mock returning (nil, nil).
Common situations: Custom or mocked searcher implementations returning nil responses without errors; lower-level client bugs or unexpected transport conditions; incorrect error handling upstream that lets a nil response propagate.
Related errors
- could not find aggregation of traceIDs
- could not find aggregation of
- root span top-hit missing _source
- file must begin with '['
- max spans count reached
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/2581a67b622b8cb1.
Report an issue: GitHub.