apache/druid · error · IllegalArgumentException
Bucket index out of range (0, )
Error message
Bucket index out of range (0, )
What it means
SpectatorHistogram stores counts indexed by Netflix Spectator PercentileBuckets, which have a fixed length. add(int bucket, long count) validates that the bucket index is within [0, PercentileBuckets.length()) and throws IAE otherwise. This guards the underlying LongAdder map from receiving invalid bucket ids.
Source
Thrown at extensions-contrib/spectator-histogram/src/main/java/org/apache/druid/spectator/histogram/SpectatorHistogram.java:305
}
void merge(SpectatorHistogram source)
{
if (source == null) {
return;
}
Short2LongOpenHashMap writableMap = writableMap();
for (Short2LongMap.Entry entry : Short2LongMaps.fastIterable(source.readableMap())) {
writableMap.addTo(entry.getShortKey(), entry.getLongValue());
this.sumOfCounts += entry.getLongValue();
}
}
// Exposed for testing
void add(int bucket, long count)
{
if (bucket >= PercentileBuckets.length() || bucket < 0) {
throw new IAE("Bucket index out of range (0, " + PercentileBuckets.length() + ")");
}
writableMap().addTo((short) bucket, count);
this.sumOfCounts += count;
}
private void add(Object key, Number value)
{
if (key instanceof String) {
this.add(Integer.parseInt((String) key), value.longValue());
return;
}
if (Number.class.isAssignableFrom(key.getClass())) {
this.add(((Number) key).intValue(), value.longValue());
return;
}
throw new IAE(
"Cannot add " + key.getClass() + "/" + value.getClass() + " to a Spectator Histogram"
);View on GitHub (pinned to 9b90983fd2)
Solutions
- Convert raw values to bucket indices with PercentileBuckets.indexOf(long value) before inserting.
- Validate serialized map keys are in [0, PercentileBuckets.length()) before passing them to deserialize/add.
- Use the public insert(Number) API instead of the package-private add(int, long) unless you already hold a valid bucket index.
Example fix
// before histogram.add(rawValue, 1); // rawValue is a measurement, not a bucket index // after int bucket = PercentileBuckets.indexOf(rawValue); histogram.add(bucket, 1);
Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidBucket(long idx) {
return idx >= 0 && idx < PercentileBuckets.length();
} Type guard
null
Try / catch
try {
histogram.insert(value);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Bucket index out of range")) {
throw new IAE("Value does not map to a valid percentile bucket", e);
}
throw e;
} Prevention
- Always convert raw measurements via PercentileBuckets.indexOf before bucket-level calls.
- Use the public insert(Number) API rather than the package-private add(int, long).
- Validate keys of maps destined for deserialize against PercentileBuckets.length().
When it happens
Trigger: Calling insert(value) with a numeric key whose intValue() is negative or >= PercentileBuckets.length(); calling package-private add(bucket, count) directly in tests with an out-of-range bucket; deserializing a map that contains keys outside the valid bucket range.
Common situations: Users feeding raw values (e.g. latencies in arbitrary units) instead of bucket indices via deserialize; a corrupted or hand-edited serialized histogram containing bad keys; test code guessing bucket ids instead of using PercentileBuckets.indexOf.
Related errors
- Cannot add / to a Spectator Histogram
- Expected a Number, but received [%s] of type [%s]
- Index[%d] >= size[%d]
- A-Not-B requires at least 1 sketch
- Illegal number of fields[%d], must be > 1
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/0fcf6540649d61ae.
Report an issue: GitHub.