apache/druid · error · AggregatorFactoryNotMergeableException
AggregatorFactoryNotMergeableException
Error message
AggregatorFactoryNotMergeableException
What it means
SimpleDoubleAggregatorFactory.getMergingFactory throws AggregatorFactoryNotMergeableException when another aggregator factory does not have the same name and the same class. Druid needs to combine partial aggregation results from multiple shards/segments, and this only works when both factories represent the same double aggregation over the same output name. The exception signals the query planner asked to merge two incompatible aggregations.
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/SimpleDoubleAggregatorFactory.java:196
{
return object;
}
@Override
public List<String> requiredFields()
{
return fieldName != null
? Collections.singletonList(fieldName)
: fieldExpression.get().analyzeInputs().getRequiredBindingsList();
}
@Override
public AggregatorFactory getMergingFactory(AggregatorFactory other) throws AggregatorFactoryNotMergeableException
{
if (other.getName().equals(this.getName()) && this.getClass() == other.getClass()) {
return getCombiningFactory();
} else {
throw new AggregatorFactoryNotMergeableException(this, other);
}
}
@Override
public int hashCode()
{
return Objects.hash(fieldName, expression, name);
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure both aggregation sides use the same output name for the double aggregator
- Ensure both sides use the same aggregator type (doubleSum/doubleMin/doubleMax/doubleFirst etc.) so classes match
- Rewrite the query so subquery and outer aggregations are consistent, or remove the merging requirement by pushing aggregations into the inner query
- If data was ingested with an older schema, re-ingest or use a query that avoids cross-shard merge of mismatched factories
Example fix
// before
Aggregations: aggColumnAggregate: { type: "doubleSum", name: "sum_x" } and { type: "longSum", name: "sum_x" }
// after
Use consistent factories:
{ type: "doubleSum", name: "sum_x" } on both subquery and outer query Defensive patterns
Strategy: validation
Validate before calling
boolean mergeable(AggregatorFactory a, AggregatorFactory b) {
return a.getName().equals(b.getName()) && a.getClass() == b.getClass();
} Type guard
boolean isMergeableDoublePair(AggregatorFactory other, SimpleDoubleAggregatorFactory self) {
return other instanceof SimpleDoubleAggregatorFactory && other.getName().equals(self.getName());
} Try / catch
try {
AggregatorFactory merged = factory.getMergingFactory(other);
} catch (AggregatorFactoryNotMergeableException e) {
LOGGER.warn(e, "Skipping merge for incompatible aggregator factories: %s vs %s", e.getFactory1(), e.getFactory2());
} Prevention
- Keep aggregator output names unique and consistent across subqueries and outer queries
- Use the same aggregator class/type for the same output name everywhere in a query
- Test distributed (multi-segment) execution of complex queries, not just single-segment
- After schema changes, verify historical segments match current metric types
When it happens
Trigger: Distributing a query across segments where one shard's aggregator factory for a given name is a SimpleDoubleAggregatorFactory but the other shard yields a different class (or a different output name), causing DruidAggregationQueryTool/merge logic to call getMergingFactory with a mismatched other.
Common situations: Queries mixing subqueries or datasources where one side has a double aggregator named x and the other has a differently-named or differently-typed aggregator; post-inception changes where subquery pushdown rewrites aggregations and names diverge between layers.
Related errors
- AggregatorFactoryNotMergeableException
- AggregatorFactoryNotMergeableException
- Emit called unexpectedly before service start
- Got an exception while parsing file [%s]
- Unable to copy key [%s] to file [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/7cde687c045949dc.
Report an issue: GitHub.