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

  1. Rebuild the SAI index (nodetool rebuild_index or DROP/CREATE INDEX).
  2. Restore the affected SSTable/index components from a snapshot or backup.
  3. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/a8451949ffc02f9e. Report an issue: GitHub.