apache/druid · error · java.lang.UnsupportedOperationException

HyperUniquesBufferAggregator does not support getLong()

Error message

HyperUniquesBufferAggregator does not support getLong()

What it means

HyperUniquesAggregator aggregates HyperLogLog sketches which only support metric extraction as a complex object (HyperLogLogCollector). Druid's Aggregator interface requires getLong/getDouble/getFloat stubs, but sketch aggregation has no meaningful numeric value, so these accessors unconditionally throw UnsupportedOperationException to fail fast rather than return garbage.

Solutions

  1. Do not read a hyperUnique aggregator as a long; use its finalized form (approxCountDistinct / HyperUniqueFinalizingPostAggregator or the estimate of the returned HyperLogLogCollector).
  2. If a numeric value is needed in a post-aggregator, wrap the metric with HyperUniqueFinalizingPostAggregator (or in newer Druid use the sketch finalization) so the estimate is computed before numeric use.
  3. If you implement custom aggregation code, check aggregator instanceof ComplexAggregator / cast to the expected type before calling getLong().

Example fix

// before
PostAggregator est = new ArithmeticPostAggregator("est", "+", Collections.singletonList(new FieldAccessPostAggregator("u", "uniques")));
// after
PostAggregator est = new HyperUniqueFinalizingPostAggregator("est", "uniques");
Defensive patterns

Strategy: type-guard

Validate before calling

if (aggregator instanceof HyperUniquesAggregator || aggregator instanceof HyperUniquesBufferAggregator) { throw new IllegalStateException("Use HyperUniqueFinalizingPostAggregator for hyperUnique metrics, not numeric accessors"); }

Type guard

boolean isSketchAggregator(Object agg) { return agg instanceof HyperUniquesAggregator || agg instanceof HyperUniquesBufferAggregator; }

Try / catch

try { return agg.getLong(); } catch (UnsupportedOperationException e) { return ((HyperLogLogCollector) agg.get()).estimate().longValue(); }

Prevention

When it happens

Trigger: A query, post-aggregator, or aggregation code path calls getLong() on an uniques ('HLLSketch') aggregator — e.g. using a long-typed post-aggregator or a numeric accessor on a theta/hyperUnique metric instead of the appropriate sketch finalizer.

Common situations: Users write a custom post-aggregator or JavaScript post-aggregator over a hyperUnique metric expecting a numeric value; queries with finalization disabled reading raw aggregator state; version upgrades where the engine calls numeric accessors for a metric that only supports estimate()/sketch extraction.

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/841fe110327832d5. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesBufferAggregator.java:106

  }

  @Override
  public Object get(ByteBuffer buf, int position)
  {
    return doGet(buf, position);
  }

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


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

  @Override
  public double getDouble(ByteBuffer buf, int position)
  {
    throw new UnsupportedOperationException("HyperUniquesBufferAggregator 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)