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
- Do not read a hyperUnique aggregator as a long; use its finalized form (approxCountDistinct / HyperUniqueFinalizingPostAggregator or the estimate of the returned HyperLogLogCollector).
- 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.
- 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
- Never attach numeric post-aggregators directly to hyperUnique metrics; wrap with HyperUniqueFinalizingPostAggregator.
- Check the metric type from the aggregator factory before choosing numeric extraction code paths.
- Treat sketch aggregators as complex metrics: always finalize before arithmetic.
- Prefer ApproximateHistogram/sketch-aware query APIs over raw accessor calls.
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
- HyperUniquesAggregator does not support getDouble()
- HyperUniquesAggregator does not support getFloat()
- HyperUniquesAggregator does not support getLong()
- HyperUniquesBufferAggregator does not support getDouble()
- Aggregator[ ] cannot vectorize
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)