apache/druid · error · IllegalArgumentException
Index[%d] >= size[%d]
Error message
Index[%d] >= size[%d]
What it means
Bounds-check guard replicating Guava's Preconditions.checkElementIndex behavior for GenericIndexed: callers attempt to read element at 'index' and this fires when index >= the number of elements stored in the index, meaning the reader requested an element beyond what was serialized into the file. It indicates an out-of-range lookup into a file-backed GenericIndexed, typically from corrupt metadata, a stale dictionary reference, or an off-by-one caller; keep index within 0..size-1.
Source
Thrown at processing/src/main/java/org/apache/druid/segment/data/GenericIndexed.java:498
inspector.visit("strategy", strategy);
}
}
/**
* Checks if {@code index} a valid `element index` in GenericIndexed.
* Similar to Preconditions.checkElementIndex() except this method throws {@link IAE} with custom error message.
* <p>
* Used here to get existing behavior(same error message and exception) of V1 GenericIndexed.
*
* @param index index identifying an element of an GenericIndexed.
*/
protected void checkIndex(int index)
{
if (index < 0) {
throw new IAE("Index[%s] < 0", index);
}
if (index >= size) {
throw new IAE("Index[%d] >= size[%d]", index, size);
}
}
public Class<? extends T> getClazz()
{
return strategy.getClazz();
}
@Override
public int size()
{
return size;
}
/**
* Returns the index of "value" in this GenericIndexed object, or (-(insertion point) - 1) if the value is not
* present, in the manner of Arrays.binarySearch. This strengthens the contract of Indexed, which only guarantees
* that values-not-found will return some negative number.View on GitHub (pinned to 9b90983fd2)
Solutions
- Bound loops with strict < size(), using indexed.size() rather than cached numbers.
- Guard reads: if (index >= indexed.size()) return null or throw a controlled error.
- Refresh any persisted cardinality/size values so they match the current segment.
Example fix
// before for (int i = 0; i <= indexed.size(); i++) use(indexed.get(i)); // after for (int i = 0; i < indexed.size(); i++) use(indexed.get(i));
Defensive patterns
Strategy: type-guard
Validate before calling
if (index >= indexed.size()) throw new IndexOutOfBoundsException("index " + index + " >= " + indexed.size()); Type guard
boolean inBounds(Indexed<?> idx, int i) { return i >= 0 && i < idx.size(); } Try / catch
try { return indexed.get(i); } catch (IAE e) { log.warn("stale size metadata?", e); return null; } Prevention
- Use strict '<' in loops over Indexed.size()
- Refresh cached cardinality/size metadata when segments change
- Fetch size from the same Indexed instance you read from
When it happens
Trigger: Calling get(index) with index >= the number of elements in the GenericIndexed, e.g. iterating with an off-by-one bound (<= size) or using stale size metadata.
Common situations: Loops like for (i = 0; i <= dim.size(); i++), cached/stale cardinality metadata after segment replacement, or external code assuming a larger dictionary.
Related errors
- Index[%s] < 0
- Index[%s] < 0
- Column[%d] is not a valid column for segment[%s]
- Column[%d] is not a valid column for the frame based datasou
- Cannot build hash-join matcher on non-key-based condition: %
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/2ad3f2be1fff01bc.
Report an issue: GitHub.