apache/druid · error · UnsupportedOperationException

HistogramBufferAggregator does not support getLong()

Error message

HistogramBufferAggregator does not support getLong()

What it means

HistogramBufferAggregator.getLong() throws UnsupportedOperationException by design: the aggregator's result is a Histogram object stored in an off-heap buffer, and it cannot be converted to a single long. Druid's BufferAggregator interface offers getLong(), but the histogram implementation rejects it. Seeing this means a query path requested LONG access on a histogram metric.

Source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/HistogramBufferAggregator.java:99

    ByteBuffer mutationBuffer = buf.duplicate();
    mutationBuffer.position(position);
    mutationBuffer.asLongBuffer().get(bins);

    float min = mutationBuffer.getFloat(position + minOffset);
    float max = mutationBuffer.getFloat(position + maxOffset);
    return new Histogram(breaks, bins, min, max);
  }

  @Override
  public float getFloat(ByteBuffer buf, int position)
  {
    throw new UnsupportedOperationException("HistogramBufferAggregator does not support getFloat()");
  }

  @Override
  public long getLong(ByteBuffer buf, int position)
  {
    throw new UnsupportedOperationException("HistogramBufferAggregator does not support getLong()");
  }

  @Override
  public double getDouble(ByteBuffer buf, int position)
  {
    throw new UnsupportedOperationException("HistogramBufferAggregator does not support getDouble");
  }

  @Override
  public void close()
  {
    // no resources to cleanup
  }

  @Override
  public void inspectRuntimeShape(RuntimeShapeInspector inspector)
  {
    inspector.visit("selector", selector);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use get(ByteBuffer, int) to obtain the Histogram and process it as an object result.
  2. Choose a long-producing aggregator (longSum, longMax) if a BIGINT result is required.
  3. Remove LONG-typed post-aggregators or casts from the histogram metric in the query spec.
  4. Adjust custom code to branch on aggregator type before calling getLong().

Example fix

// before
long l = bufferAgg.getLong(buf, position); // throws
// after
Object val = bufferAgg.get(buf, position);
if (val instanceof Histogram) {
  int binCount = ((Histogram) val).bins.length;
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (bufferAggregator instanceof HistogramBufferAggregator) {
  // use get(buf, position) (Histogram), not getLong()
}

Type guard

boolean supportsLong(BufferAggregator agg) {
  return !(agg instanceof HistogramBufferAggregator);
}

Try / catch

try {
  value = agg.getLong(buf, position);
} catch (UnsupportedOperationException e) {
  Histogram h = (Histogram) agg.get(buf, position);
}

Prevention

When it happens

Trigger: A groupBy/timeseries query with a 'histogram' aggregator whose metric is read via getLong(ByteBuffer, int); LONG coercion of the histogram column in SQL; long-typed post-aggregators (arithmetic with long ops, longGreatest) applied to the histogram metric.

Common situations: Migrating queries from longSum to histogram without adjusting output handling; SQL planning that assigns BIGINT to the aggregation expression; custom aggregation pipelines that call getLong() generically on all buffer aggregators.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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