{"record":{"id":"b4dbdfe5b428911b","repo":"apache/cassandra","slug":"no-holder-claimed","errorCode":null,"errorMessage":"No holder claimed ","messagePattern":"No holder claimed ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java","lineNumber":936,"sourceCode":"\n    /**\n     * Should only be called holding the readLock\n     */\n    private void handleFlushNotification(Iterable<SSTableReader> added)\n    {\n        for (SSTableReader sstable : added)\n            getHolder(sstable).addSSTable(sstable);\n    }\n\n    private int getHolderIndex(SSTableReader sstable)\n    {\n        for (int i = 0; i < holders.size(); i++)\n        {\n            if (holders.get(i).managesSSTable(sstable))\n                return i;\n        }\n\n        throw new IllegalStateException(\"No holder claimed \" + sstable);\n    }\n\n    private AbstractStrategyHolder getHolder(SSTableReader sstable)\n    {\n        for (AbstractStrategyHolder holder : holders)\n        {\n            if (holder.managesSSTable(sstable))\n                return holder;\n        }\n\n        throw new IllegalStateException(\"No holder claimed \" + sstable);\n    }\n\n    private AbstractStrategyHolder getHolder(long repairedAt, TimeUUID pendingRepair, boolean isTransient)\n    {\n        return getHolder(repairedAt != ActiveRepairService.UNREPAIRED_SSTABLE,\n                         pendingRepair != ActiveRepairService.NO_PENDING_REPAIR,\n                         isTransient);","sourceCodeStart":918,"sourceCodeEnd":954,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java#L918-L954","documentation":"CompactionStrategyManager partitions a table's SSTables among holders (repaired/unrepaired, transient, pending-repair, and per-directory strategy holders). getHolderIndex(sstable) is an internal lookup that assumes every SSTable belongs to exactly one holder; if none claims it the internal bookkeeping is inconsistent, so an IllegalStateException is thrown. This is an invariant violation, not user error per se.","triggerScenarios":"An SSTableReader is passed to getHolderIndex/getHolder (e.g. via compaction task creation, sstable lifecycle operations, or nodetool sstable operations) whose location (directory index, repaired/pending-repair/transient state) does not match any registered holder - typically because disk boundaries or strategy state changed without the sstable being reclassified.","commonSituations":"Race between disk-boundary relocation/reload and compaction on the same sstable; sstables moved between directories out-of-band; bugs in pending-repair lifecycle (session finished/forgotten while sstable still tagged); running with JBOD and changing data directories.","solutions":["Restart the node - holders and disk boundaries are rebuilt on startup, reclassifying orphaned sstables","Run nodetool relocate / nodetool garbagcollect or trigger a strategy reload (nodetool reloadcompactionstrategy) to resync holder lists","Check for concurrent disk-boundary changes and ensure compaction operations are not racing a topology/directory change","If reproducible, file a Cassandra bug with the sstable descriptor and compaction strategy config"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before sstable operations, confirm the sstable is managed\nList<AbstractStrategyHolder> holders = csm.getHolders();\nboolean managed = holders.stream().anyMatch(h -> h.managesSSTable(sstable));\nif (!managed) throw new IllegalStateException(\"sstable not claimed by any holder: \" + sstable);","typeGuard":null,"tryCatchPattern":"try { idx = csm.getHolderIndex(sstable); }\ncatch (IllegalStateException e) {\n  logger.error(\"holder bookkeeping out of sync; restart/reload strategy\", e);\n  cfs.getCompactionStrategyManager().maybeReloadDiskBoundaries();\n}","preventionTips":["Avoid moving sstable files between data directories out-of-band","Do not run sstable operations concurrently with strategy reloads or relocation","Keep repair sessions properly finished/released","Run nodetool reloadcompactionstrategy after changing data directories"],"tags":["compaction","invariant","sstable","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}