{"record":{"id":"27d2367f4575d7a2","repo":"apache/cassandra","slug":"couldn-t-acquire-reference-to-the-sstable-it-m","errorCode":null,"errorMessage":"Couldn't acquire reference to the SSTable {}. It may have been removed.","messagePattern":"Couldn't acquire reference to the SSTable (.+?)\\. It may have been removed\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/index/accord/RouteSecondaryIndexBuilder.java","lineNumber":123,"sourceCode":"        {\n            if (indexSSTable(sstable))\n                return;\n        }\n    }\n\n    /**\n     * @return true if index build should be stopped\n     */\n    private boolean indexSSTable(SSTableReader sstable)\n    {\n        logger.debug(\"Starting index build on {}\", sstable.descriptor);\n\n        RouteIndexFormat.SSTableIndexWriter indexWriter = null;\n\n        Ref<? extends SSTableReader> ref = sstable.tryRef();\n        if (ref == null)\n        {\n            logger.warn(\"Couldn't acquire reference to the SSTable {}. It may have been removed.\", sstable.descriptor);\n            return false;\n        }\n\n        try (RandomAccessReader dataFile = sstable.openDataReader();\n             LifecycleTransaction txn = LifecycleTransaction.offline(OperationType.INDEX_BUILD, sstable))\n        {\n            // remove existing per column index files instead of overwriting\n            IndexDescriptor indexDescriptor = IndexDescriptor.create(sstable);\n            indexDescriptor.deleteIndex();\n\n            indexWriter = new RouteIndexFormat.SSTableIndexWriter(index, indexDescriptor);\n            indexWriter.begin();\n\n            long previousBytesRead = 0;\n\n            try (KeyIterator keys = sstable.keyIterator())\n            {\n                while (keys.hasNext())","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/accord/RouteSecondaryIndexBuilder.java#L105-L141","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["No action needed if the SSTable was legitimately compacted — the index will be built for surviving SSTables and new ones as they are flushed.","If the message appears for all SSTables repeatedly, verify no LifecycleTransaction leak is removing readers prematurely.","Re-run the index build (nodetool rebuild_index) if the final index is incomplete."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// before building, filter out SSTables already compacting away\nList<SSTableReader> live = sstables.stream().filter(s -> s.tryRef() != null).collect(toList());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat single occurrences as benign compaction races.","Avoid triggering index builds concurrent with aggressive cleanup/tombstone compaction.","Verify build completeness after the build finishes; rebuild if SSTables were skipped."],"tags":["sstable","reference-counting","index-build","accord"],"backgroundTag":"resource-not-found","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}