apache/cassandra · error · IndexOutOfBoundsException
Index should be between [0, %d), but was %d.
Error message
Index should be between [0, %d), but was %d.
What it means
AbstractBlockPackedReader.get() validates that the requested valueIndex lies within [0, valueCount) before decoding a block-packed long. An out-of-range index indicates a caller is reading a SAI block-packed file (e.g. a balanced-tree or postings structure) with a position beyond the stored element count, usually meaning metadata/descriptor corruption. The check uses [0, valueCount) despite the '0' in the message string being valueCount — the message formats the bound correctly as the first argument.
Source
Thrown at src/java/org/apache/cassandra/index/sai/disk/v1/bitpack/AbstractBlockPackedReader.java:57
private long lastIndex; // the last index visited by token -> row ID searches
AbstractBlockPackedReader(IndexInput indexInput, byte[] blockBitsPerValue, int blockShift, int blockMask, long valueCount)
{
this.blockShift = blockShift;
this.blockMask = blockMask;
this.valueCount = valueCount;
this.input = new SeekingRandomAccessInput(indexInput);
this.blockBitsPerValue = blockBitsPerValue;
}
protected abstract long blockOffsetAt(int block);
@Override
public long get(final long valueIndex)
{
if (valueIndex < 0 || valueIndex >= valueCount)
{
throw new IndexOutOfBoundsException(String.format("Index should be between [0, %d), but was %d.", valueCount, valueIndex));
}
int blockIndex = (int) (valueIndex >>> blockShift);
int inBlockIndex = (int) (valueIndex & blockMask);
byte bitsPerValue = blockBitsPerValue[blockIndex];
final LongValues subReader = bitsPerValue == 0 ? LongValues.ZEROES
: DirectReader.getInstance(input, bitsPerValue, blockOffsetAt(blockIndex));
return delta(blockIndex, inBlockIndex) + subReader.get(inBlockIndex);
}
@Override
public long length()
{
return valueCount;
}
@Override
public long indexOf(long value)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Run nodetool rebuil_index / drop and recreate the SAI index to regenerate the corrupted index files.
- Verify index component metadata (valueCount) matches the segment file being read.
- Fix the caller to clamp/validate the index against the reader's valueCount before calling get().
Example fix
// before long v = reader.get(pointId); // after if (pointId < 0 || pointId >= reader.valueCount) pointId = Math.min(Math.max(pointId, 0), reader.valueCount - 1); long v = reader.get(pointId);
Defensive patterns
Strategy: try-catch
Validate before calling
if (valueIndex < 0 || valueIndex >= valueCount) return fallbackValue; // skip get()
Type guard
boolean inRange(long i, long count) { return i >= 0 && i < count; } Try / catch
try { return reader.get(idx); } catch (IndexOutOfBoundsException e) { log.warn("Corrupt index read", e); return null; } Prevention
- Clamp indices to valueCount from segment metadata before reads.
- Monitor for SAI corruption via checksum verification and rebuild indexes proactively after crashes.
When it happens
Trigger: Calling get(valueIndex) with valueIndex < 0 or valueIndex >= valueCount; internally invoked by midVal and binarySearchBlock during tree searches when a stored tree position or block offset is corrupt.
Common situations: Corrupted or truncated SAI index files on disk, an index descriptor mismatch after a failed compaction/upgrade, or hand-crafted readers seeking with point ids not clamped to the metadata key count.
Related errors
- The target point id [%d] cannot be less than 0 or greater th
- Invalid block offset %d for postings block idx %d
- Postings list #%s block is corrupted. Bits per value should
- The tree position is less than zero.
- The postings position is less than zero.
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/bd3a123f8b2e895c.
Report an issue: GitHub.