apache/druid · error · AggregatorFactoryNotMergeableException
AggregatorFactoryNotMergeableException(this, other)
Error message
AggregatorFactoryNotMergeableException(this, other)
What it means
Druid's mergeable-aggregator protocol requires getMergingFactory(other) to return a factory that can merge with this one. When the other factory is not a DoublesSketchAggregatorFactory (different concrete type), the factory throws AggregatorFactoryNotMergeableException. This protects the sketch union from combining incompatible aggregations.
Source
Thrown at extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchAggregatorFactory.java:387
public AggregatorFactory getMergingFactory(AggregatorFactory other) throws AggregatorFactoryNotMergeableException
{
if (other.getName().equals(this.getName()) && other instanceof DoublesSketchAggregatorFactory) {
final DoublesSketchAggregatorFactory castedOther = (DoublesSketchAggregatorFactory) other;
if (castedOther.shouldFinalize == shouldFinalize) {
// DoublesUnion supports inputs with different k.
// The result will have effective k between the specified k and the minimum k from all input sketches
// to achieve higher accuracy as much as possible.
return new DoublesSketchMergeAggregatorFactory(
name,
Math.max(k, castedOther.k),
Math.max(maxStreamLength, castedOther.maxStreamLength),
shouldFinalize
);
}
}
throw new AggregatorFactoryNotMergeableException(this, other);
}
@Nullable
@Override
public Object finalizeComputation(@Nullable final Object object)
{
if (!shouldFinalize || object == null) {
return object;
}
return ((DoublesSketch) object).getN();
}
/**
* actual type is {@link DoublesSketch}
*/
@Override
public ColumnType getIntermediateType()View on GitHub (pinned to 9b90983fd2)
Solutions
- Use the same quantilesDoublesSketch aggregator type in both the inner and outer query specs for the sketch column
- Ensure the two factories being merged have identical names, k, maxStreamLength and shouldFinalize settings
- If you only need a finalized metric, finalize the sketch in the inner query instead of re-aggregating with a different type
Example fix
// before: outer query uses doubleSum over a sketch column
{"type":"doubleSum","name":"sk","fieldName":"sk"}
// after: merge sketches with the same sketch aggregator
{"type":"quantilesDoublesSketch","name":"sk","fieldName":"sk","k":128} Defensive patterns
Strategy: try-catch
Validate before calling
if (!(other instanceof DoublesSketchAggregatorFactory)
|| !((DoublesSketchAggregatorFactory) other).getName().equals(this.getName())) {
throw new IllegalArgumentException("Cannot merge: outer aggregator must be a matching quantilesDoublesSketch");
} Type guard
boolean mergeable(AggregatorFactory a, AggregatorFactory b) {
return a.getName().equals(b.getName()) && a.getClass().equals(b.getClass());
} Try / catch
try {
AggregatorFactory merged = factory.getMergingFactory(other);
} catch (AggregatorFactoryNotMergeableException e) {
throw new IllegalStateException("Mismatched aggregator types for column " + factory.getName() + ": " + e.getMessage());
} Prevention
- Use identical quantilesDoublesSketch aggregator specs (same name, k, maxStreamLength, shouldFinalize) in inner and outer queries
- Never re-aggregate a sketch column with plain numeric aggregators like doubleSum
- Test distributed group-by plans when changing aggregator types
When it happens
Trigger: Calling getMergingFactory with an AggregatorFactory whose getName() matches but whose concrete type is not DoublesSketchAggregatorFactory, e.g. merging a quantilesDoublesSketch agg with an HllSketch, theta, or plain doubleSum aggregator in the same merge position of a distributed group-by.
Common situations: Distributed group-by queries where an outer query re-aggregates a sketch column with a mismatched aggregator type; rewriting queries by hand and swapping the aggregator type in the outer spec; tooling that merges query specs automatically.
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
- Not implemented
- Object cannot be deserialized to a Moments Sketch:
- not implemented
- Not implemented
- Not implemented
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/747c8cdc77c51b0f.
Report an issue: GitHub.