apache/druid · error · IllegalArgumentException
Expected a number or an instance of MergingDigest, but…
Error message
Expected a number or an instance of MergingDigest, but received [%s] of type [%s]
What it means
TDigestSketchBufferAggregator.aggregate() only knows how to fold two input shapes: a raw Number (added as a single value) and an already-built MergingDigest (merged into the sketch). When the selector's getObject() returns any other type, the column does not hold valid t-digest sketch data and aggregation cannot continue, so it throws instead of silently skipping a non-null, non-numeric value.
Solutions
- Fix the input so the aggregated column contains numbers or MergingDigest values (e.g. correct the parser/flattener spec)
- If ingesting from serialized sketches, ensure the tdigestsketch complex metric serde is used so values deserialized to MergingDigest
- Inspect the offending rows and cast or transform non-numeric values before ingestion
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at extensions-contrib/tdigestsketch/src/main/java/org/apache/druid/query/aggregation/tdigestsketch/TDigestSketchBufferAggregator.java:80 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ba47f1301876a806.
Report an issue: GitHub.
Appendix: source
Thrown at extensions-contrib/tdigestsketch/src/main/java/org/apache/druid/query/aggregation/tdigestsketch/TDigestSketchBufferAggregator.java:80
{
MergingDigest emptyDigest = new MergingDigest(compression);
addToCache(buffer, position, emptyDigest);
}
@Override
public void aggregate(ByteBuffer buffer, int position)
{
Object x = selector.getObject();
if (x == null) {
return;
}
MergingDigest sketch = sketchCache.get(buffer).get(position);
if (x instanceof Number) {
sketch.add(((Number) x).doubleValue());
} else if (x instanceof MergingDigest) {
sketch.add((MergingDigest) x);
} else {
throw new IAE(
"Expected a number or an instance of MergingDigest, but received [%s] of type [%s]",
x,
x.getClass()
);
}
}
@Override
public Object get(final ByteBuffer buffer, final int position)
{
// sketchCache is an IdentityHashMap where the reference of buffer is used for equality checks.
// So the returned object isn't impacted by the changes in the buffer object made by concurrent threads.
return sketchCache.get(buffer).get(position);
}
@Override
public float getFloat(final ByteBuffer buffer, final int position)
{View on GitHub (pinned to 9b90983fd2)