apache/cassandra · error · CorruptIndexException
The tree position is less than zero.
Error message
The tree position is less than zero.
What it means
The NumericIndexSegmentSearcher constructor reads the segment metadata root positions for the BALANCED_TREE and POSTING_LISTS components. A negative tree position is impossible in a valid segment file, so it throws a Lucene CorruptIndexException immediately — a cheap validity check before opening the block-balanced tree reader. (Note the postings check incorrectly labels itself BALANCED_TREE in the message.)
Source
Thrown at src/java/org/apache/cassandra/index/sai/disk/v1/segment/NumericIndexSegmentSearcher.java:63
* Executes {@link Expression}s against the balanced tree for an individual index segment.
*/
public class NumericIndexSegmentSearcher extends IndexSegmentSearcher
{
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final BlockBalancedTreeReader treeReader;
private final QueryEventListener.BalancedTreeEventListener perColumnEventListener;
NumericIndexSegmentSearcher(PrimaryKeyMap.Factory primaryKeyMapFactory,
PerColumnIndexFiles perIndexFiles,
SegmentMetadata segmentMetadata,
StorageAttachedIndex index) throws IOException
{
super(primaryKeyMapFactory, perIndexFiles, segmentMetadata, index);
final long treePosition = metadata.getIndexRoot(IndexComponent.BALANCED_TREE);
if (treePosition < 0)
throw new CorruptIndexException(index.identifier().logMessage("The tree position is less than zero."), IndexComponent.BALANCED_TREE.name);
final long postingsPosition = metadata.getIndexRoot(IndexComponent.POSTING_LISTS);
if (postingsPosition < 0)
throw new CorruptIndexException(index.identifier().logMessage("The postings position is less than zero."), IndexComponent.BALANCED_TREE.name);
treeReader = new BlockBalancedTreeReader(index.identifier(),
indexFiles.balancedTree(),
treePosition,
indexFiles.postingLists(),
postingsPosition);
perColumnEventListener = (QueryEventListener.BalancedTreeEventListener)index.columnQueryMetrics();
}
@Override
public long indexFileCacheSize()
{
return treeReader.memoryUsage();
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Rebuild the SAI index (nodetool rebuild_index or DROP/CREATE INDEX).
- Restore the affected SSTable/index components from a snapshot or backup.
- Check Cassandra version and disk health; if reproducible after normal flush, report as an internal write-path bug.
Defensive patterns
Strategy: try-catch
Validate before calling
long pos = segmentMetadata.getIndexRoot(IndexComponent.BALANCED_TREE); if (pos < 0) flagCorruptSegment();
Try / catch
try { searcher = new NumericIndexSegmentSearcher(...); } catch (CorruptIndexException e) { log.error("Corrupt numeric segment metadata", e); markSegmentUnreadable(); } Prevention
- Verify index metadata roots on segment open and quarantine bad segments.
- Rebuild the index and restore components from snapshots after corruption is detected.
When it happens
Trigger: Opening a numeric SAI segment whose metadata.getIndexRoot(IndexComponent.BALANCED_TREE) is < 0, i.e. metadata written without a tree root or pointing past invalid bounds.
Common situations: Partially written/truncated segment files after an unclean shutdown, disk corruption, or descriptor/metadata version mismatch after an upgrade or failed flush.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Index should be between [0, %d), but was %d.
- 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 postings position is less than zero.
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a8451949ffc02f9e.
Report an issue: GitHub.