apache/druid · error · IllegalArgumentException

Expected a number or an instance of DDSketch, but received [

Error message

Expected a number or an instance of DDSketch, but received [%s] of type [%s]

What it means

DDSketchBufferAggregator.aggregate() only accepts Number or DDSketch inputs for the off-heap aggregation path; any other object type throws this IAE. It mirrors the non-buffer aggregator and signals the input selector produced an unexpected type during query execution.

Source

Thrown at extensions-contrib/ddsketch/src/main/java/org/apache/druid/query/aggregation/ddsketch/DDSketchBufferAggregator.java:83

    mutationBuffer.position(position);
    addToCache(buffer, position, sketch);
  }

  @Override
  public void aggregate(ByteBuffer buffer, int position)
  {
    Object x = selector.getObject();
    if (x == null) {
      return;
    }
    DDSketch sketch = sketchCache.get(buffer).get(position);

    if (x instanceof Number) {
      sketch.accept(((Number) x).doubleValue());
    } else if (x instanceof DDSketch) {
      sketch.mergeWith((DDSketch) x);
    } else {
      throw new IAE(
          "Expected a number or an instance of DDSketch, 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.
    DDSketch obj = sketchCache.get(buffer).get(position);
    return obj;
  }

  @Override
  public float getFloat(final ByteBuffer buffer, final int position)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Ensure the input field is numeric or a DDSketch object; fix the fieldName/column type.
  2. Insert an expression aggregator that casts to double before the ddsketch aggregation.
  3. Use ddsketch-produced sketches only; do not merge sketches from other libraries.
  4. Validate column types via the segment metadata query before adding the aggregation.

Example fix

// before
{"type": "ddsketch", "name": "sk", "fieldName": "eventValue"} // eventValue is VARCHAR
// after
{"type": "expression", "name": "valueNum", "expression": "CAST(\"eventValue\" AS DOUBLE)", "outputType": "DOUBLE"} then ddsketch on valueNum
Defensive patterns

Strategy: type-guard

Validate before calling

// before query: run segment metadata query to confirm the field is numeric or COMPLEX<ddsketch>

Type guard

Object x = selector.getObject();
if (!(x instanceof Number) && !(x instanceof DDSketch)) {
  log.warn("Ignoring non-numeric ddsketch input: %s", x);
  return;
}

Try / catch

try {
  agg.aggregate(x);
} catch (IllegalArgumentException e) {
  log.warn(e, "Bad ddsketch input type, dropping value");
}

Prevention

When it happens

Trigger: Aggregating a string or complex non-sketch column with the ddsketch aggregator when the buffer-based execution path is used, or feeding a wrong-typed post-aggregator result into a second ddsketch aggregation.

Common situations: fieldName pointing at a dimension/string metric, array or nested values, or mixing sketch types produced by other aggregators (e.g. datasketches quantiles) with ddsketch.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/9ea9313fa93ca761. Report an issue: GitHub.