jaegertracing/jaeger · error
could not find aggregation of
Error message
could not find aggregation of
What it means
This error is raised by aggregationKeys when the search response has an Aggregations section but does not contain the requested terms aggregation (resp.Aggregations.Terms(name) returns !ok). The message is dynamic: "could not find aggregation of " + name. The caller cannot extract bucket keys without the expected aggregation.
Source
Thrown at internal/storage/v2/elasticsearch/tracestore/core/service_operation.go:188
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))
h.Write([]byte(s.OperationName))
return strconv.FormatUint(h.Sum64(), 16)
}
View on GitHub (pinned to 806f444784)
Solutions
- Verify the request sent to ES actually includes the named terms aggregation matching the name passed to aggregationKeys.
- Check Elasticsearch/OpenSearch version compatibility and that the response includes aggregations.
- Inspect intermediate proxies/plugins that could strip or rename aggregations in responses.
- Update the Jaeger storage layer if using an older/newer IDL or client with changed aggregation names.
Defensive patterns
Strategy: type-guard
Validate before calling
if resp != nil && resp.Aggregations != nil {
if _, ok := resp.Aggregations.Terms("services"); !ok {
return fmt.Errorf("missing services aggregation in response")
}
} Type guard
func hasTermsAgg(r *esclient.SearchResponse, name string) bool {
return r != nil && r.Aggregations != nil && func() bool { _, ok := r.Aggregations.Terms(name); return ok }()
} Try / catch
keys, err := aggregationKeys(resp, aggName)
if err != nil && strings.HasPrefix(err.Error(), "could not find aggregation of ") {
// missing aggregation: log full response for diagnosis
log.Printf("aggregation %q missing in ES response", aggName)
} Prevention
- Keep aggregation names in shared constants so query and parser never drift apart.
- Verify ES/OpenSearch versions against the Jaeger support matrix after upgrades.
- Log raw responses when aggregation parsing fails to spot proxies stripping fields.
When it happens
Trigger: getServices or getOperations requesting a named terms aggregation (e.g. "services" or "operations") that is absent from the ES response — typically because the query sent to Elasticsearch did not include that aggregation, or the response was produced by a differently shaped query.
Common situations: Version skew where the aggregation name or query structure changed; a proxy rewriting the search body; misconfigured requests that silently drop aggregations (e.g. size/termination settings); testing against a hand-built response missing the aggregation.
Related errors
- could not find aggregation of traceIDs
- nil search response
- root span top-hit missing _source
- aggregation bucket has a non-string key: %w
- failed to convert aggregations to metrics: %w
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/a9bd5430165274d2.
Report an issue: GitHub.