apache/druid · error · UnsupportedOperationException
[%s] does not implement makeAggregateCombiner()
Error message
[%s] does not implement makeAggregateCombiner()
What it means
AggregatorFactory.makeAggregateCombiner() is an abstract-style hook that must return an AggregateCombiner used when merging pre-aggregated segments (e.g. during IndexMerger merges). The base class throws this UOE to signal that the concrete aggregator factory does not support combining-based merging, so an attempt to merge segments containing this aggregator cannot proceed.
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/AggregatorFactory.java:130
* @param rhs The right hand side of the combine
*
* @return an object representing the combination of lhs and rhs, this can be a new object or a mutation of the inputs
*/
@Nullable
public abstract Object combine(@Nullable Object lhs, @Nullable Object rhs);
/**
* Creates an AggregateCombiner to fold rollup aggregation results from serveral "rows" of different indexes during
* index merging. AggregateCombiner implements the same logic as {@link #combine}, with the difference that it uses
* {@link org.apache.druid.segment.ColumnValueSelector} and it's subinterfaces to get inputs and implements {@code
* ColumnValueSelector} to provide output.
*
* @see AggregateCombiner
* @see org.apache.druid.segment.IndexMerger
*/
public AggregateCombiner makeAggregateCombiner()
{
throw new UOE("[%s] does not implement makeAggregateCombiner()", this.getClass().getName());
}
/**
* Creates an {@link AggregateCombiner} which supports nullability.
* Implementations of {@link AggregatorFactory} which need to Support Nullable Aggregations are encouraged
* to extend {@link NullableNumericAggregatorFactory} instead of overriding this method.
* Default implementation calls {@link #makeAggregateCombiner()} for backwards compatibility.
*
* @see AggregateCombiner
* @see NullableNumericAggregatorFactory
*/
public AggregateCombiner makeNullableAggregateCombiner()
{
return makeAggregateCombiner();
}
/**
* Returns an AggregatorFactory that can be used to combine the output of aggregators from this factory. It is usedView on GitHub (pinned to 9b90983fd2)
Solutions
- Override makeAggregateCombiner() in your AggregatorFactory subclass to return a proper AggregateCombiner for your aggregator
- If supporting nullable aggregations, extend NullableNumericAggregatorFactory instead of implementing the method directly
- Use an aggregator type that supports combining (implements getCombiningFactory/makeAggregateCombiner) in merge scenarios
Example fix
// before
public class MyAggregatorFactory extends AggregatorFactory {
// no makeAggregateCombiner override
}
// after
public class MyAggregatorFactory extends AggregatorFactory {
@Override
public AggregateCombiner makeAggregateCombiner() {
return new MyAggregateCombiner();
}
} Defensive patterns
Strategy: type-guard
Validate before calling
// before merging
if (!(factory instanceof AggregatorFactory) || factory.getClass().equals(AggregatorFactory.class)) {
throw new IllegalStateException("Aggregator must override makeAggregateCombiner()");
} Type guard
boolean supportsCombining(AggregatorFactory f) {
try { f.makeAggregateCombiner(); return true; } catch (UnsupportedOperationException e) { return false; }
} Try / catch
try {
combiner = factory.makeAggregateCombiner();
} catch (UnsupportedOperationException e) {
log.error("Aggregator %s cannot merge segments", factory.getClass(), e);
throw new QueryInterruptedException("aggregator-not-mergeable");
} Prevention
- Always override makeAggregateCombiner in custom AggregatorFactory subclasses
- Prefer extending NullableNumericAggregatorFactory for nullable numeric aggregators
- Test custom aggregators with segment merging (rollup) scenarios before production
When it happens
Trigger: Calling makeAggregateCombiner() (directly or via combiner()/makeNullableAggregateCombiner()) on an AggregatorFactory subclass that has not overridden the method, then using it in segment merging or nullable aggregation paths.
Common situations: Custom aggregator implementations missing the override; using an aggregator type in a rollup/merge context that only supports incremental aggregation; version changes where combining support became required for a code path.
Understand the failure class
Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.
Related errors
- AggregatorFactoryNotMergeableException(this, other)
- 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/003784f9530a2de9.
Report an issue: GitHub.