{"record":{"id":"b5ee8b7efac6e909","repo":"apache/cassandra","slug":"prepare-phase-for-incremental-repair-session-s-ha-b5ee8b","errorCode":null,"errorMessage":"Prepare phase for incremental repair session %s has failed because it encountered intersecting sstables belonging to another incremental repair session. This is caused by starting multiple conflicting incremental repairs at the same time. Conflicting anticompactions: ...","messagePattern":"Prepare phase for incremental repair session (.+?) has failed because it encountered intersecting sstables belonging to another incremental repair session\\. This is caused by starting multiple conflicting incremental repairs at the same time\\. Conflicting anticompactions: \\.\\.\\.","errorType":"exception","errorClass":"SSTableAcquisitionException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/repair/PendingAntiCompaction.java","lineNumber":162,"sourceCode":"                                                   \"caused by starting an incremental repair session before a previous one has completed. \" +\n                                                   \"Check nodetool repair_admin for hung sessions and fix them.\", prsid, metadata.pendingRepair);\n                    throw new SSTableAcquisitionException(message);\n                }\n                return false;\n            }\n            Collection<CompactionInfo> cis = CompactionManager.instance.active.getCompactionsForSSTable(sstable, OperationType.ANTICOMPACTION);\n            if (cis != null && !cis.isEmpty())\n            {\n                // todo: start tracking the parent repair session id that created the anticompaction to be able to give a better error messsage here:\n                StringBuilder sb = new StringBuilder();\n                sb.append(\"Prepare phase for incremental repair session \");\n                sb.append(prsid);\n                sb.append(\" has failed because it encountered intersecting sstables belonging to another incremental repair session. \");\n                sb.append(\"This is caused by starting multiple conflicting incremental repairs at the same time. \");\n                sb.append(\"Conflicting anticompactions: \");\n                for (CompactionInfo ci : cis)\n                    sb.append(ci.getTaskId() == null ? \"no compaction id\" : ci.getTaskId()).append(':').append(ci.getSSTables()).append(',');\n                throw new SSTableAcquisitionException(sb.toString());\n            }\n            return true;\n        }\n    }\n\n    public static class AcquisitionCallable implements Callable<AcquireResult>\n    {\n        private final ColumnFamilyStore cfs;\n        private final TimeUUID sessionID;\n        private final AntiCompactionPredicate predicate;\n        private final int acquireRetrySeconds;\n        private final int acquireSleepMillis;\n\n        @VisibleForTesting\n        public AcquisitionCallable(ColumnFamilyStore cfs, Collection<Range<Token>> ranges, TimeUUID sessionID, int acquireRetrySeconds, int acquireSleepMillis)\n        {\n            this(cfs, sessionID, acquireRetrySeconds, acquireSleepMillis, new AntiCompactionPredicate(ranges, sessionID));\n        }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/repair/PendingAntiCompaction.java#L144-L180","documentation":"During the prepare phase of an incremental repair, Cassandra acquires SSTables for anticompaction. If the SSTables it needs intersect with SSTables already owned by another concurrent incremental repair session, the acquisition fails and this SSTableAcquisitionException is thrown, aborting the repair. Incremental repair requires exclusive SSTable ownership per session, so overlapping sessions are fundamentally conflicting.","triggerScenarios":"Running `nodetool repair --incremental` on the same table from two clients/nodes at overlapping times; a scheduled repair job overlapping a manually triggered one; a previous repair session's anticompaction still in progress when a new incremental repair starts.","commonSituations":"Cron-based repair schedules overlapping with ad-hoc repairs; monitoring systems re-triggering repairs because a prior one appeared stuck; multi-DC repairs started at similar times on the same token ranges.","solutions":["Ensure only one incremental repair runs at a time per table/token range (use repair scheduling tools like Reaper with locking).","Wait for the conflicting repair/anticompaction to finish, then retry the repair.","Serialize repair jobs via `nodetool tpstats`/`nodetool compactionstats` checks before starting a new incremental repair.","If incremental repair is not required, use full (pr -partitioner-range) repairs or subrange repairs on disjoint ranges."],"exampleFix":"// before: two overlapping crons\n0 2 * * * nodetool repair -inc myks mytable\n0 2 * * * nodetool repair -inc myks mytable\n// after: single serialized scheduler (e.g. Reaper) or staggered crons\n0 2 * * * nodetool repair -inc myks mytable\n0 2 * * * sleep 3600 && nodetool repair -inc otherks othertable","handlingStrategy":"validation","validationCode":"if (CompactionManager.instance.getPendingTasks() > 0 || repairJobsInProgress(myks, mytable) > 0) { throw new IllegalStateException(\"another incremental repair in progress\"); }","typeGuard":null,"tryCatchPattern":"try { nodetool-repair-inc } catch (SSTableAcquisitionException e) { waitForConflictingRepair(); retryWithBackoff(); }","preventionTips":["Use a single repair coordinator (e.g. Reaper) with job locking","Serialize incremental repairs per table/range in cron schedules","Monitor compactionstats for active anticompactions before starting repairs"],"tags":["repair","anticompaction","concurrency","sstables"],"backgroundTag":"conflicting-config-options","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"}