apache/druid · error · IllegalStateException
Not enough space for aggregators, needed [%,d] bytes but…
Error message
Not enough space for aggregators, needed [%,d] bytes but have only [%,d].
What it means
In the vectorized timeseries path, aggregator intermediates are stored in a single pooled ByteBuffer. Before processing, Druid checks the aggregators' spaceNeeded() against the buffer's remaining bytes and aborts with ISE if the buffer from the pool is too small to hold the aggregator state.
Solutions
- Increase druid.processing.buffer.sizeBytes so it exceeds the aggregators' spaceNeeded()
- Reduce the number/size of aggregators in the query or split the query
- Disable vectorization for the affected query (druid.query.vectorize=false) to fall back to the non-vectorized engine
- Verify the processing buffer pool is actually sized after restarts (check startup logs for buffer pool warnings)
Example fix
// before (runtime.properties) druid.processing.buffer.sizeBytes=50000000 // after druid.processing.buffer.sizeBytes=1073741824
Defensive patterns
Strategy: validation
Validate before calling
// before running vectorized: check config in runtime.properties // assert druid.processing.buffer.sizeBytes > sum of aggregator spaceNeeded();
Type guard
static boolean bufferSufficient(BufferAggregator[] aggs, ByteBuffer buf) {
long need = 0; /* sum agg space needs */ return need <= buf.remaining();
} Try / catch
try { return vectorizedProcess(...); }
catch (IllegalStateException e) {
if (e.getMessage().contains("Not enough space for aggregators")) { return nonVectorizedProcess(...); }
throw e;
} Prevention
- Size druid.processing.buffer.sizeBytes for worst-case aggregator counts
- Avoid huge numbers of aggregators in single timeseries queries
- Set druid.query.vectorize=false for sketch-heavy queries on small nodes
When it happens
Trigger: Running a vectorized timeseries query whose aggregators require more intermediate buffer space than the configured aggregation buffer pool provides (small druid.processing.buffer.sizeBytes plus many/large aggregators).
Common situations: Queries with many aggregators or large sketch/HLL aggregators on nodes with small processing buffers, misconfigured druid.processing.buffer.sizeBytes, buffer pool contention after config change without restart.
Related errors
- attempt to get boolean[] null vector from string[] only…
- attempt to get double[] from string[] only scalar binding
- attempt to get long[] from string[] only scalar binding
- buffer for list is too small, was
- Got a [ ] which isn't a
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/d3ba39843b127f0d.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/timeseries/TimeseriesQueryEngine.java:172
gran,
queryInterval
);
if (granularizer == null) {
return Sequences.withBaggage(Sequences.empty(), closer);
}
final VectorColumnSelectorFactory columnSelectorFactory = cursor.getColumnSelectorFactory();
final AggregatorAdapters aggregators =
AggregatorAdapters.factorizeVector(columnSelectorFactory, query.getAggregatorSpecs());
closer.register(aggregators::reset);
final ResourceHolder<ByteBuffer> bufferHolder = closer.register(bufferPool.take());
final ByteBuffer buffer = bufferHolder.get();
if (aggregators.spaceNeeded() > buffer.remaining()) {
throw new ISE(
"Not enough space for aggregators, needed [%,d] bytes but have only [%,d].",
aggregators.spaceNeeded(),
buffer.remaining()
);
}
return Sequences.withBaggage(
Sequences
.simple(granularizer.getBucketIterable())
.map(
bucketInterval -> {
// Whether or not the current bucket is empty
boolean emptyBucket = true;
while (!cursor.isDone()) {
granularizer.setCurrentOffsets(bucketInterval);
if (granularizer.getEndOffset() > granularizer.getStartOffset()) {View on GitHub (pinned to 9b90983fd2)