{"record":{"id":"291223b28785f415","repo":"apache/cassandra","slug":"unable-to-recover-d-partitions-that-were-skipped","errorCode":null,"errorMessage":"Unable to recover %d partitions that were skipped.  You can attempt manual recovery from the pre-scrub snapshot.  You can also run nodetool repair to transfer the data from a healthy replica, if any","messagePattern":"Unable to recover (.+?) partitions that were skipped\\.  You can attempt manual recovery from the pre-scrub snapshot\\.  You can also run nodetool repair to transfer the data from a healthy replica, if any","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/sstable/format/SortedTableScrubber.java","lineNumber":227,"sourceCode":"        {\n            if (transaction.isOffline())\n                finished.forEach(sstable -> sstable.selfRef().release());\n        }\n\n        outputSummary(finished);\n    }\n\n    protected abstract void scrubInternal(SSTableRewriter writer) throws IOException;\n\n    private void outputSummary(List<SSTableReader> finished)\n    {\n        if (!finished.isEmpty())\n        {\n            outputHandler.output(\"Scrub of %s complete: %d partitions in new sstable and %d empty (tombstoned) partitions dropped\", sstable, goodPartitions, emptyPartitions);\n            if (negativeLocalDeletionInfoMetrics.fixedRows > 0)\n                outputHandler.output(\"Fixed %d rows with overflowed local deletion time.\", negativeLocalDeletionInfoMetrics.fixedRows);\n            if (badPartitions > 0)\n                outputHandler.warn(\"Unable to recover %d partitions that were skipped.  You can attempt manual recovery from the pre-scrub snapshot.  You can also run nodetool repair to transfer the data from a healthy replica, if any\", badPartitions);\n        }\n        else\n        {\n            if (badPartitions > 0)\n                outputHandler.warn(\"No valid partitions found while scrubbing %s; it is marked for deletion now. If you want to attempt manual recovery, you can find a copy in the pre-scrub snapshot\", sstable);\n            else\n                outputHandler.output(\"Scrub of %s complete; looks like all %d partitions were tombstoned\", sstable, emptyPartitions);\n        }\n    }\n\n    private SSTableReader writeOutOfOrderPartitions(StatsMetadata metadata)\n    {\n        // out of order partitions/rows, but no bad partition found - we can keep our repairedAt time\n        long repairedAt = badPartitions > 0 ? ActiveRepairService.UNREPAIRED_SSTABLE : sstable.getSSTableMetadata().repairedAt;\n        SSTableReader newInOrderSstable;\n        try (SSTableWriter inOrderWriter = CompactionManager.createWriter(cfs, destination, expectedBloomFilterSize, repairedAt, metadata.pendingRepair, metadata.isTransient, sstable, transaction))\n        {\n            for (Partition partition : outOfOrder)","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/SortedTableScrubber.java#L209-L245","documentation":"At the end of a scrub, outputSummary reports partitions that were corrupt/unreadable and had to be skipped (badPartitions > 0) while some valid data was recovered. It directs the operator to the pre-scrub snapshot for manual recovery or to run nodetool repair so a healthy replica can re-stream the lost data.","triggerScenarios":"nodetool scrub completes with some partitions unreadable due to corruption (bad checksums, truncated file, invalid structure); emitted after the new sstable(s) are written, only when finished is non-empty.","commonSituations":"See trigger scenarios.","solutions":["Run nodetool repair on the affected range/node so a healthy replica re-streams the missing partitions","If no healthy replica exists, extract the lost partitions manually from the pre-scrub snapshot sstables","Check host hardware/filesystem health (smartctl, fsck) before trusting the node again","Verify replication factor is adequate so single-replica corruption is recoverable"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// After scrub, check reported bad partitions and react:\nif (scrubReport.badPartitions > 0) { triggerRepair(keyspace, table); verifyPreScrubSnapshotExists(); }","preventionTips":["Use RF >= 3 so scrub data loss can be repaired from replicas","Take snapshots before scrubbing important tables","Monitor disk SMART/health to catch corruption early","Schedule scrub during low traffic and inspect its output"],"tags":["scrub","data-corruption","repair","data-loss"],"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"}