{"record":{"id":"ba3fac2cccf4448f","repo":"apache/cassandra","slug":"an-error-occurred-while-scrubbing-the-partition-wi-ba3fac","errorCode":null,"errorMessage":"An error occurred while scrubbing the partition with key '%s' for an index table. Scrubbing will abort for this table and the index will be rebuilt.","messagePattern":"An error occurred while scrubbing the partition with key '(.+?)' for an index table\\. Scrubbing will abort for this table and the index will be rebuilt\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/io/sstable/format/bti/BtiTableScrubber.java","lineNumber":293,"sourceCode":"            {\n                indexIterator.advance();\n            }\n            catch (Throwable th)\n            {\n                outputHandler.warn(th, \"Failed to go to the next entry in index\");\n                throw Throwables.cleaned(th);\n            }\n        }\n\n        return false;\n    }\n\n    @Override\n    protected void throwIfCannotContinue(DecoratedKey key, Throwable th)\n    {\n        if (isIndex)\n        {\n            outputHandler.warn(\"An error occurred while scrubbing the partition with key '%s' for an index table. \" +\n                               \"Scrubbing will abort for this table and the index will be rebuilt.\", keyString(key));\n            throw new IOError(th);\n        }\n\n        super.throwIfCannotContinue(key, th);\n    }\n\n    @Override\n    public void close()\n    {\n        fileAccessLock.writeLock().lock();\n        try\n        {\n            FileUtils.closeQuietly(dataFile);\n            FileUtils.closeQuietly(indexIterator);\n        }\n        finally\n        {","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/bti/BtiTableScrubber.java#L275-L311","documentation":"When scrubbing an SSTable-backed 2i (index) table hits an unrecoverable per-partition error, BtiTableScrubber.throwIfCannotContinue logs this warning, aborts the scrub for that index table by throwing IOError, and relies on the index being rebuilt instead of failing the whole scrub session. Unlike a base-table scrub (which delegates to the parent's handling), index scrub failures are treated as recoverable via rebuild.","triggerScenarios":"scrubInternal on an is index table calls throwIfCannotContinue(key, th) after an unrecoverable read error on a partition key — e.g. corrupt data in an SSTableAttachedSecondaryIndex (SAI/2i) backing sstable.","commonSituations":"Corrupted secondary-index sstables after crashes or disk errors; running nodetool scrub on a node with damaged index files; index and base table out of sync after failed compactions.","solutions":["Rebuild the index (nodetool rebuild_index or drop and re-create the index) instead of recovering the corrupt index sstable","Check the base table data is intact — the index can be safely regenerated from it","Verify disk health; repeated index corruption suggests failing storage"],"exampleFix":"// before: fighting the corrupt index sstable\n$ nodetool scrub ks tbl  // aborts on index table\n// after\n$ nodetool rebuild_index ks tbl idx_name  // index rebuilt from base data","handlingStrategy":"fallback","validationCode":"// scrub index tables only after confirming base table integrity\nboolean baseIntact = ColumnFamilyStore.getIfExists(keyspace, baseTable) != null\n        && ColumnFamilyStore.getIfExists(keyspace, baseTable).getLiveSSTables().size() > 0;\nif (!baseIntact) throw new IllegalStateException(\"Base table missing or empty; rebuild index from base data instead of scrubbing index sstables\");","typeGuard":null,"tryCatchPattern":"try {\n    ColumnFamilyStore indexCfs = ...;\n    indexCfs.scrub(...);\n} catch (IOError e) {\n    logger.warn(\"Index scrub aborted; rebuilding index {}\", indexCfs, e);\n    indexCfs.indexManager().rebuildIndexesBlocking(Set.of(indexName));\n}","preventionTips":["Treat index sstable corruption as expected: plan on rebuild_index rather than scrub recovery","Keep base-table snapshots; indexes can always be regenerated from base data","After crashes, run rebuild_index proactively if index sstables show checksum/IO errors","Watch for repeated index corruption as a sign of failing disks"],"tags":["scrub","secondary-index","data-corruption","storage"],"backgroundTag":"checksum-mismatch","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"}