apache/cassandra · error · UnsupportedOperationException
You can't compact sstables from different pending repair ses
Error message
You can't compact sstables from different pending repair sessions
What it means
When sstables are pending an incremental repair (isPendingRepair), each belongs to one pending repair session identified by its pendingRepair TimeUUID. validateForCompaction throws UnsupportedOperationException if a compaction input mixes sstables from different pending-repair sessions, because compacting them would merge anti-compacted data belonging to distinct repair sessions and corrupt repair bookkeeping.
Source
Thrown at src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java:1231
private void validateForCompaction(Iterable<SSTableReader> input)
{
readLock.lock();
try
{
SSTableReader firstSSTable = Iterables.getFirst(input, null);
assert firstSSTable != null;
boolean repaired = firstSSTable.isRepaired();
int firstIndex = compactionStrategyIndexFor(firstSSTable);
boolean isPending = firstSSTable.isPendingRepair();
TimeUUID pendingRepair = firstSSTable.getSSTableMetadata().pendingRepair;
for (SSTableReader sstable : input)
{
if (sstable.isRepaired() != repaired)
throw new UnsupportedOperationException("You can't mix repaired and unrepaired data in a compaction");
if (firstIndex != compactionStrategyIndexFor(sstable))
throw new UnsupportedOperationException("You can't mix sstables from different directories in a compaction");
if (isPending && !pendingRepair.equals(sstable.getSSTableMetadata().pendingRepair))
throw new UnsupportedOperationException("You can't compact sstables from different pending repair sessions");
}
}
finally
{
readLock.unlock();
}
}
public CompactionTasks getMaximalTasks(final long gcBefore, final boolean splitOutput, int permittedParallelism, OperationType operationType)
{
maybeReloadDiskBoundaries();
// runWithCompactionsDisabled cancels active compactions and disables them, then we are able
// to make the repaired/unrepaired strategies mark their own sstables as compacting. Once the
// sstables are marked the compactions are re-enabled
return cfs.runWithCompactionsDisabled(() -> {
List<AbstractCompactionTask> tasks = new ArrayList<>();
readLock.lock();
tryView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Wait for the incremental repairs to finish (or release the sessions) so pending sstables are transitioned out of pending state, then compact
- Group sstables by pendingRepair id and issue one compaction per session (only while the session is still active is even that restricted)
- Use repair_admin to cancel/abort stale sessions, then nodetool garbagcollect or restart cleanup to clear pending markers
- Avoid user-defined compaction of pending sstables entirely; let repair finish first
Example fix
// before getUserDefinedTasks(pendingSstables, gcBefore); // multiple sessions // after Map<TimeUUID, List<SSTableReader>> bySession = pendingSstables.stream().collect(Collectors.groupingBy(s -> s.getSSTableMetadata().pendingRepair)); bySession.values().forEach(g -> getUserDefinedTasks(g, gcBefore));
Defensive patterns
Strategy: validation
Validate before calling
boolean multipleSessions = sstables.stream()
.filter(SSTableReader::isPendingRepair)
.map(s -> s.getSSTableMetadata().pendingRepair).distinct().count() > 1;
if (multipleSessions) throw new IllegalArgumentException("one compaction per pending repair session"); Try / catch
try { getUserDefinedTasks(input, gcBefore); }
catch (UnsupportedOperationException e) {
// wait for repair sessions to finish or group by pendingRepair id and retry
} Prevention
- Never manually compact pending-repair sstables; wait for incremental repair to complete
- Group inputs by SSTableMetadata.pendingRepair when scripting repair tooling
- Avoid concurrent incremental repairs on the same table
- Use repair_admin to clean up abandoned sessions before compaction
When it happens
Trigger: User-defined compaction selecting pending-repair sstables from more than one incremental repair session (different pendingRepair ids) while the first sstable isPending - checked via sstable.getSSTableMetadata().pendingRepair inequality.
Common situations: Running concurrent incremental repairs on the same table then attempting manual compaction of pending sstables; repair sessions abandoned without release; repair-adjacent tooling that collects all pending sstables into one compact call.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- You can't mix repaired and unrepaired data in a compaction
- Prepare phase for incremental repair session %s was unable t
- No holder claimed isPendingRepair: %s, isPendingRepair %s
- You can't mix sstables from different directories in a compa
- Attempting to compact pending repair sstables with sstables
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a22a4bda9a7e0f9f.
Report an issue: GitHub.