apache/druid · error · IllegalArgumentException
Invalid maxLoadFactor
Error message
Invalid maxLoadFactor[%f], must be < 1.0
What it means
BufferHashGrouper's maxLoadFactor controls how full the open-addressing hash table may get before regrouping. A value >= 1.0 would prevent the table from ever resizing safely, so the constructor rejects it with an IAE.
Solutions
- Set maxLoadFactor to a fraction in (0, 1.0), e.g. 0.7 (default 0.85+ ranges)
- Remove the explicit config so the DEFAULT_MAX_LOAD_FACTOR applies
- Validate the config value before constructing BufferHashGrouper
- If a percentage is being used, divide by 100
Example fix
// before "maxLoadFactor": 1.0 // after "maxLoadFactor": 0.7
Defensive patterns
Strategy: validation
Validate before calling
if (maxLoadFactor <= 0 || maxLoadFactor >= 1.0f) {
throw new IllegalArgumentException("maxLoadFactor must be in (0, 1.0), got " + maxLoadFactor);
} Type guard
boolean isValidLoadFactor(float f) { return f > 0f && f < 1.0f; } Try / catch
try { new BufferHashGrouper(..., maxLoadFactor, ...); } catch (IAE e) { if (e.getMessage().contains("maxLoadFactor")) { log config error; use default; } } Prevention
- Express load factors as fractions, never percentages
- Add config schema validation for groupBy tuning keys
- Document valid range (0, 1.0) in config examples
When it happens
Trigger: Configuring the groupBy buffer grouper with druid.query.groupBy.maxOnDiskStorage / buffer grouper maxLoadFactor settings (via GroupByQueryConfig or ByteBufferMatcher config) where maxLoadFactor <= 0 falls back to default but maxLoadFactor >= 1.0 throws — e.g. passing 1.0 or 1.5 in a JSON config override.
Common situations: Copy-pasting tuning configs with loadFactor 1.0 assuming 'use full buffer'; wrong units (percentage 100 vs fraction 1.0); auto-generated configs dividing by zero.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- At most one of 'druid.broker.segment.watchedTiers' and…
- bitmapEncoding[ ] does not match indexSpec.bitmap[ ]
- buffer for list is too small, was
- Cannot mix sortable and unsortable key columns
- Compression value [ ] is greater than the max allowed…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/8ec1334f93b6d2a7.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/BufferHashGrouper.java:70
private ByteBufferIntList offsetList;
public BufferHashGrouper(
final Supplier<ByteBuffer> bufferSupplier,
final KeySerde<KeyType> keySerde,
final AggregatorAdapters aggregators,
final int bufferGrouperMaxSize,
final float maxLoadFactor,
final int initialBuckets,
final boolean useDefaultSorting
)
{
super(bufferSupplier, keySerde, aggregators, HASH_SIZE + keySerde.keySize(), bufferGrouperMaxSize);
this.maxLoadFactor = maxLoadFactor > 0 ? maxLoadFactor : DEFAULT_MAX_LOAD_FACTOR;
this.initialBuckets = initialBuckets > 0 ? Math.max(MIN_INITIAL_BUCKETS, initialBuckets) : DEFAULT_INITIAL_BUCKETS;
if (this.maxLoadFactor >= 1.0f) {
throw new IAE("Invalid maxLoadFactor[%f], must be < 1.0", maxLoadFactor);
}
this.bucketSize = HASH_SIZE + keySerde.keySize() + aggregators.spaceNeeded();
this.useDefaultSorting = useDefaultSorting;
}
@Override
public void init()
{
if (!initialized) {
ByteBuffer buffer = bufferSupplier.get();
int hashTableSize = ByteBufferHashTable.calculateTableArenaSizeWithPerBucketAdditionalSize(
buffer.capacity(),
bucketSize,
Integer.BYTES
);
View on GitHub (pinned to 9b90983fd2)