{"record":{"id":"1da979f0c9ec524c","repo":"apache/cassandra","slug":"failed-setting-repairedat-to-d-on-s-repairedat","errorCode":null,"errorMessage":"Failed setting repairedAt to %d on %s (repairedAt is %d)","messagePattern":"Failed setting repairedAt to (.+?) on (.+?) \\(repairedAt is (.+?)\\)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java","lineNumber":1535,"sourceCode":"            try\n            {\n                // if there was an exception mutating repairedAt, we should still notify for the\n                // sstables that we were able to modify successfully before releasing the lock\n                cfs.getTracker().notifySSTableRepairedStatusChanged(changed);\n            }\n            finally\n            {\n                writeLock.unlock();\n            }\n        }\n    }\n\n    private static void verifyMetadata(SSTableReader sstable, long repairedAt, TimeUUID pendingRepair, boolean isTransient)\n    {\n        if (!Objects.equals(pendingRepair, sstable.getPendingRepair()))\n            throw new IllegalStateException(String.format(\"Failed setting pending repair to %s on %s (pending repair is %s)\", pendingRepair, sstable, sstable.getPendingRepair()));\n        if (repairedAt != sstable.getRepairedAt())\n            throw new IllegalStateException(String.format(\"Failed setting repairedAt to %d on %s (repairedAt is %d)\", repairedAt, sstable, sstable.getRepairedAt()));\n        if (isTransient != sstable.isTransient())\n            throw new IllegalStateException(String.format(\"Failed setting isTransient to %b on %s (isTransient is %b)\", isTransient, sstable, sstable.isTransient()));\n    }\n\n    public CleanupSummary releaseRepairData(Collection<TimeUUID> sessions)\n    {\n        List<CleanupTask> cleanupTasks = new ArrayList<>();\n        readLock.lock();\n        try\n        {\n            for (PendingRepairManager prm : Iterables.concat(pendingRepairs.getManagers(), transientRepairs.getManagers()))\n                cleanupTasks.add(prm.releaseSessionData(sessions));\n        }\n        finally\n        {\n            readLock.unlock();\n        }\n","sourceCodeStart":1517,"sourceCodeEnd":1553,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java#L1517-L1553","documentation":"The repairedAt branch of verifyMetadata: after CompactionStrategyManager writes a repairedAt timestamp to an sstable (mutateRepaired path used by full/incremental repair and anticompaction), the method re-reads sstable.getRepairedAt() and throws IllegalStateException if it differs from the requested value. It indicates the repair-metadata update did not stick, usually due to a concurrent mutation on the same sstable.","triggerScenarios":"Setting repairedAt during incremental repair session promotion (UNREPAIRED_SSTABLE -> timestamp) or when transitioning transient->repaired, followed by verification against the live metadata which reflects a different value because another writer mutated repairedAt in between.","commonSituations":"Two repair sessions finalizing over the same sstable; repair finalization racing with compaction or cleanup that resets repaired state; upgrade-time sstable metadata rewrite conflicts.","solutions":["Re-run repair for the affected ranges so the repairedAt timestamp is recomputed and rewritten","Retry after concurrent repair/compaction activity completes","Serialize repair operations on a table (avoid overlapping incremental repairs)","If it occurs with no concurrent activity, file a Cassandra bug with sstablemetadata output"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"long current = sstable.getRepairedAt();\nif (current != expectedOldValue)\n    logger.warn(\"repairedAt already changed to {} on {}\", current, sstable); // skip redundant mutation","typeGuard":null,"tryCatchPattern":"try { mutateAndVerify(sstable, repairedAt); }\ncatch (IllegalStateException e) {\n  // treat as benign race; repair will re-attempt, or re-run repair for the range\n}","preventionTips":["Avoid concurrent repair sessions on the same table","Check getRepairedAt() before writing to skip no-op mutations","Run repair finalization single-threaded per sstable","Re-run repair if repairedAt discrepancies appear in logs"],"tags":["repair","race-condition","sstable-metadata","internal-error"],"backgroundTag":"invalid-state-transition","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"}