apache/cassandra · error · IllegalStateException

Couldn't acquire reference to the sstable

Error message

Couldn't acquire reference to the sstable: %s

What it means

SSTableIndex construction takes a reference on the owning SSTable (referent.tryRef()). If the SSTable was just replaced/deleted by compaction or cleanup, tryRef returns null and the constructor throws this IllegalStateException, preventing an index on a dead SSTable from being used.

Solutions

  1. Retry the query — the per-sstable index view is rebuilt and the dead SSTable is dropped from the set.
  2. Force a compaction or rebuild the SASI index (nodetool compact, or drop/recreate the index) so indexes reference live SSTables.
  3. If it recurs persistently, check for GC/ref-tracking bugs or mismatched on-disk index files and run nodetool scrub/upgradeSSTables.
Defensive patterns

Strategy: retry

Try / catch

try {
    return runSasiQuery();
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Couldn't acquire reference to the sstable"))
        return retryWithBackoff(runSasiQuery); // index view rebuilt on retry
    throw e;
}

Prevention

When it happens

Trigger: Building a SSTableIndex during query planning or compaction when the referenced SSTable is concurrently discarded: the Ref.tryRef() fails because refcount is zero or the ref tracker is already cleaned up.

Common situations: Heavy compaction activity concurrent with queries on SASI-indexed tables; node restart/cleanup racing with index reads; loading a corrupted or already-obsoleted per-sstable index file.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/index/sasi/SSTableIndex.java:59

import org.apache.cassandra.utils.concurrent.Ref;

public class SSTableIndex implements Comparable<SSTableIndex>
{
    private final ColumnIndex columnIndex;
    private final Ref<SSTableReader> sstableRef;
    private final SSTableReader sstable;
    private final OnDiskIndex index;
    private final AtomicInteger references = new AtomicInteger(1);
    private final AtomicBoolean obsolete = new AtomicBoolean(false);

    public SSTableIndex(ColumnIndex index, File indexFile, SSTableReader referent)
    {
        this.columnIndex = index;
        this.sstableRef = referent.tryRef();
        this.sstable = sstableRef.get();

        if (sstable == null)
            throw new IllegalStateException("Couldn't acquire reference to the sstable: " + referent);

        AbstractType<?> validator = columnIndex.getValidator();

        assert validator != null;
        assert indexFile.exists() : String.format("SSTable %s should have index %s.",
                sstable.getFilename(),
                columnIndex.getIndexName());

        this.index = new OnDiskIndex(indexFile, validator, new DecoratedKeyFetcher(sstable));
    }

    public OnDiskIndexBuilder.Mode mode()
    {
        return index.mode();
    }

    public boolean hasMarkedPartials()
    {

View on GitHub (pinned to 88fd0f6a0e)