apache/cassandra · warning

Couldn't acquire reference to the SSTable {}. It may have be

Error message

Couldn't acquire reference to the SSTable {}. It may have been removed.

What it means

RouteSecondaryIndexBuilder builds Accord route index components by ref-counting each SSTable. If sstable.tryRef() returns null the SSTable has already been fully released (deleted by compaction or cleanup), so the builder logs this WARN and returns false, skipping that SSTable rather than failing the whole index build.

Source

Thrown at src/java/org/apache/cassandra/index/accord/RouteSecondaryIndexBuilder.java:123

        {
            if (indexSSTable(sstable))
                return;
        }
    }

    /**
     * @return true if index build should be stopped
     */
    private boolean indexSSTable(SSTableReader sstable)
    {
        logger.debug("Starting index build on {}", sstable.descriptor);

        RouteIndexFormat.SSTableIndexWriter indexWriter = null;

        Ref<? extends SSTableReader> ref = sstable.tryRef();
        if (ref == null)
        {
            logger.warn("Couldn't acquire reference to the SSTable {}. It may have been removed.", sstable.descriptor);
            return false;
        }

        try (RandomAccessReader dataFile = sstable.openDataReader();
             LifecycleTransaction txn = LifecycleTransaction.offline(OperationType.INDEX_BUILD, sstable))
        {
            // remove existing per column index files instead of overwriting
            IndexDescriptor indexDescriptor = IndexDescriptor.create(sstable);
            indexDescriptor.deleteIndex();

            indexWriter = new RouteIndexFormat.SSTableIndexWriter(index, indexDescriptor);
            indexWriter.begin();

            long previousBytesRead = 0;

            try (KeyIterator keys = sstable.keyIterator())
            {
                while (keys.hasNext())

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. No action needed if the SSTable was legitimately compacted — the index will be built for surviving SSTables and new ones as they are flushed.
  2. If the message appears for all SSTables repeatedly, verify no LifecycleTransaction leak is removing readers prematurely.
  3. Re-run the index build (nodetool rebuild_index) if the final index is incomplete.
Defensive patterns

Strategy: fallback

Validate before calling

// before building, filter out SSTables already compacting away
List<SSTableReader> live = sstables.stream().filter(s -> s.tryRef() != null).collect(toList());

Prevention

When it happens

Trigger: Building the route index for an SSTable that was concurrently removed by compaction/garbage collection between listing the SSTables and trying to reference them — a benign race, not data corruption.

Common situations: Starting an index build while aggressive compaction or TTL cleanup is deleting SSTables; running offline index builds against a table with pending cleanup; simultaneous LifecycleTransactions removing readers.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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