elastic/elasticsearch · error · IllegalArgumentException
Aggregator [{name}] of type [{getType()}] cannot accept sub-
Error message
Aggregator [{name}] of type [{getType()}] cannot accept sub-aggregations What it means
Thrown by the LeafOnly clone constructor of ArrayValuesSourceAggregationBuilder when factoriesBuilder.count() > 0 — i.e., during a rewrite/clone the builder discovers it has sub-aggregations attached. LeafOnly aggregations (multi-field variants of metrics like matrix_stats) produce a single metric value and cannot have sub-aggregations nested under them, so attaching any is a structural error caught at rewrite time.
Source
Thrown at modules/aggregations/src/main/java/org/elasticsearch/aggregations/metric/ArrayValuesSourceAggregationBuilder.java:48
import java.util.Objects;
public abstract class ArrayValuesSourceAggregationBuilder<AB extends ArrayValuesSourceAggregationBuilder<AB>> extends
AbstractAggregationBuilder<AB> {
public static final ParseField MULTIVALUE_MODE_FIELD = new ParseField("mode");
public abstract static class LeafOnly<AB extends ArrayValuesSourceAggregationBuilder<AB>> extends ArrayValuesSourceAggregationBuilder<
AB> {
protected LeafOnly(String name) {
super(name);
}
@SuppressWarnings("this-escape")
protected LeafOnly(LeafOnly<AB> clone, Builder factoriesBuilder, Map<String, Object> metadata) {
super(clone, factoriesBuilder, metadata);
if (factoriesBuilder.count() > 0) {
throw new IllegalArgumentException("Aggregator [" + name + "] of type [" + getType() + "] cannot accept sub-aggregations");
}
}
/**
* Read from a stream
*/
protected LeafOnly(StreamInput in) throws IOException {
super(in);
}
@Override
public AB subAggregations(Builder subFactories) {
throw new IllegalArgumentException("Aggregator [" + name + "] of type [" + getType() + "] cannot accept sub-aggregations");
}
@Override
public final BucketCardinality bucketCardinality() {
return BucketCardinality.NONE;View on GitHub (pinned to db6a809a66)
Solutions
- Remove the sub-aggregations from the LeafOnly metric — move them to a parent bucket aggregation if needed.
- Check the aggregation type's documentation: metric aggregations like matrix_stats are leaf-only and cannot nest sub-aggregations.
- Restructure so the metric is a sibling, not a parent, of the sub-aggregation.
Example fix
// before: sub-aggregation nested under a leaf-only metric
{"matrix_stats":{"fields":["a","b"],"aggs":{"sub":{"avg":{"field":"c"}}}}}
// after: make them siblings
{"aggs":{"m":{"matrix_stats":{"fields":["a","b"]}},"sub":{"avg":{"field":"c"}}}} Defensive patterns
Strategy: type-guard
Validate before calling
if (agg instanceof ArrayValuesSourceAggregationBuilder.LeafOnly<?> && subFactories.count() > 0) {
throw new IllegalArgumentException("leaf-only aggregation cannot have sub-aggregations");
} Type guard
boolean isLeafOnly(org.elasticsearch.search.aggregations.AggregationBuilder b) {
return b instanceof ArrayValuesSourceAggregationBuilder.LeafOnly<?>;
} Prevention
- Never nest sub-aggregations under leaf-only metrics (matrix_stats, etc.).
- In generic builders, check BucketCardinality.NONE before attaching children.
- Make sub-aggregations siblings of leaf metrics.
When it happens
Trigger: Calling .subAggregations(...)/.addAggregation(...) on a LeafOnly aggregation (or constructing one with a non-empty factories builder) and then triggering rewrite (e.g. via build() or the search execution path). The error surfaces during the clone-with-rewrite step rather than at the moment of attachment because the constructor path is the one that validates.
Common situations: Users nesting a sub-aggregation under a metric that does not support it (e.g. under matrix_stats). Programmatic builders that generically attach sub-aggregations to any aggregation type. REST requests with a `aggs` block nested inside a leaf-only metric.
Related errors
- [${name}] is missing : filters parameter
- [separator] must not be null: [${name}]
- [key] must not be null
- [filter] must not be null
- minimum_interval must be one of [{ALLOWED_INTERVALS.values()
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/8b95ccbda3720ce6.
Report an issue: GitHub.