{"record":{"id":"bd3a123f8b2e895c","repo":"apache/cassandra","slug":"index-should-be-between-0-d-but-was-d","errorCode":null,"errorMessage":"Index should be between [0, %d), but was %d.","messagePattern":"Index should be between \\[0, (.+?)\\), but was (.+?)\\.","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/index/sai/disk/v1/bitpack/AbstractBlockPackedReader.java","lineNumber":57,"sourceCode":"    private long lastIndex; // the last index visited by token -> row ID searches\n\n    AbstractBlockPackedReader(IndexInput indexInput, byte[] blockBitsPerValue, int blockShift, int blockMask, long valueCount)\n    {\n        this.blockShift = blockShift;\n        this.blockMask = blockMask;\n        this.valueCount = valueCount;\n        this.input = new SeekingRandomAccessInput(indexInput);\n        this.blockBitsPerValue = blockBitsPerValue;\n    }\n\n    protected abstract long blockOffsetAt(int block);\n\n    @Override\n    public long get(final long valueIndex)\n    {\n        if (valueIndex < 0 || valueIndex >= valueCount)\n        {\n            throw new IndexOutOfBoundsException(String.format(\"Index should be between [0, %d), but was %d.\", valueCount, valueIndex));\n        }\n\n        int blockIndex = (int) (valueIndex >>> blockShift);\n        int inBlockIndex = (int) (valueIndex & blockMask);\n        byte bitsPerValue = blockBitsPerValue[blockIndex];\n        final LongValues subReader = bitsPerValue == 0 ? LongValues.ZEROES\n                                                       : DirectReader.getInstance(input, bitsPerValue, blockOffsetAt(blockIndex));\n        return delta(blockIndex, inBlockIndex) + subReader.get(inBlockIndex);\n    }\n\n    @Override\n    public long length()\n    {\n        return valueCount;\n    }\n\n    @Override\n    public long indexOf(long value)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sai/disk/v1/bitpack/AbstractBlockPackedReader.java#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before\nlong v = reader.get(pointId);\n// after\nif (pointId < 0 || pointId >= reader.valueCount) pointId = Math.min(Math.max(pointId, 0), reader.valueCount - 1);\nlong v = reader.get(pointId);","handlingStrategy":"try-catch","validationCode":"if (valueIndex < 0 || valueIndex >= valueCount) return fallbackValue; // skip get()","typeGuard":"boolean inRange(long i, long count) { return i >= 0 && i < count; }","tryCatchPattern":"try { return reader.get(idx); } catch (IndexOutOfBoundsException e) { log.warn(\"Corrupt index read\", e); return null; }","preventionTips":["Clamp indices to valueCount from segment metadata before reads.","Monitor for SAI corruption via checksum verification and rebuild indexes proactively after crashes."],"tags":["cassandra","sai","index-corruption","bounds-check"],"backgroundTag":"index-out-of-bounds","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}