apache/druid · error · AggregatorFactoryNotMergeableException
can't merge [%s : %s] and [%s : %s] , with detailed info [%s
Error message
can't merge [%s : %s] and [%s : %s] , with detailed info [%s] and [%s]
What it means
getMergingFactory() merges two AggregatorFactory instances only when they have the same output name and equal combining factories. If the names differ or the combining factories are not equal, it throws AggregatorFactoryNotMergeableException, indicating pre-aggregated inputs cannot be merged under one aggregator spec.
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/AggregatorFactory.java:194
* by the "other" aggregator factory, and we want to do some additional combining of them. This happens, for example,
* when compacting two segments together that both have a metric column with the same name. (Even though the name of
* the column is the same, the aggregator factory used to create it may be different from segment to segment.)
*
* This method may throw {@link AggregatorFactoryNotMergeableException}, meaning that "this" and "other" are not
* compatible and values from one cannot sensibly be combined with values from the other.
*
* @return a new Factory that can be used for merging the output of aggregators from this factory and other.
*
* @see #getCombiningFactory() which is equivalent to {@code foo.getMergingFactory(foo)} (when "this" and "other"
* are the same instance).
*/
public AggregatorFactory getMergingFactory(AggregatorFactory other) throws AggregatorFactoryNotMergeableException
{
final AggregatorFactory combiningFactory = this.getCombiningFactory();
if (other.getName().equals(this.getName()) && combiningFactory.equals(other.getCombiningFactory())) {
return combiningFactory;
} else {
throw new AggregatorFactoryNotMergeableException(this, other);
}
}
/**
* This was previously used by group-by v1 and will be removed in a future release
*/
@Deprecated
public List<AggregatorFactory> getRequiredColumns()
{
throw new UnsupportedOperationException(
"Do not call or implement this method, it is deprecated and will be removed in a future releases."
);
}
/**
* A method that knows how to "deserialize" the object from whatever form it might have been put into
* in order to transfer via JSON.
*View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure both aggregator factories share the same output name and identical combining parameters (type, fieldName/expression)
- Inspect the detailed info in the exception message to find the mismatched attribute and align the two specs
- Adjust the query or ingestion spec so all merged sources use compatible aggregators
Example fix
// before
new DoubleSumAggregatorFactory("sum", "col1") merged with new DoubleSumAggregatorFactory("sum", "col2")
// after
new DoubleSumAggregatorFactory("sum", "col") merged with new DoubleSumAggregatorFactory("sum", "col") Defensive patterns
Strategy: validation
Validate before calling
// before merging
if (!a.getName().equals(b.getName()) || !a.getCombiningFactory().equals(b.getCombiningFactory())) {
throw new IllegalArgumentException("Aggregators not mergeable: " + a.getName() + " vs " + b.getName());
} Type guard
boolean mergeable(AggregatorFactory a, AggregatorFactory b) {
return a.getName().equals(b.getName()) && a.getCombiningFactory().equals(b.getCombiningFactory());
} Try / catch
try {
merged = factory.getMergingFactory(other);
} catch (AggregatorFactoryNotMergeableException e) {
log.error("Cannot merge aggregators", e);
throw new IAE("Align aggregator names and parameters across datasources");
} Prevention
- Keep aggregator output names and parameters identical across datasources you plan to merge
- Compare combining factories when composing multi-datasource schemas
- Review 'detailed info' in the exception to locate the mismatched attribute
When it happens
Trigger: Calling getMergingFactory(other) where other.getName() differs from this.getName(), or where this.getCombiningFactory() does not equal other.getCombiningFactory() (different aggregator types, different fieldNames, expressions, or parameters).
Common situations: Merging segments/datasources whose schemas declare different aggregators under the same output name; typos in fieldName or different aggregators (doubleSum vs longSum) across datasources; subquery/post-aggregation name mismatches.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- AggregatorFactoryNotMergeableException(this, other)
- Incompatible aggregator factories, [this] and [other]
- [%s] does not implement makeAggregateCombiner()
- AggregatorFactoryNotMergeableException
- Emit called unexpectedly before service start
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/21ab38c9faba4ca3.
Report an issue: GitHub.