apache/cassandra · error · IllegalSSTableArgumentException
sstable is not pending repair
Error message
sstable is not pending repair
What it means
PendingRepairManager APIs (getOrCreate, getScanners) require a non-null pending repair ID because they manage only incremental-repair SSTables. checkPendingID throws IllegalSSTableArgumentException when a null ID is passed, indicating the caller passed an sstable that is not part of any pending repair.
Source
Thrown at src/java/org/apache/cassandra/db/compaction/PendingRepairManager.java:129
{
strategy = get(id);
if (strategy == null)
{
logger.debug("Creating {}.{} compaction strategy for pending repair: {}", cfs.metadata.keyspace, cfs.metadata.name, id);
strategy = cfs.createCompactionStrategyInstance(params);
strategies = mapBuilder().putAll(strategies).put(id, strategy).build();
}
}
}
return strategy;
}
private static void checkPendingID(TimeUUID pendingID)
{
if (pendingID == null)
{
throw new IllegalSSTableArgumentException("sstable is not pending repair");
}
}
AbstractCompactionStrategy getOrCreate(SSTableReader sstable)
{
return getOrCreate(sstable.getSSTableMetadata().pendingRepair);
}
private synchronized void removeSessionIfEmpty(TimeUUID sessionID)
{
if (!strategies.containsKey(sessionID) || !strategies.get(sessionID).getSSTables().isEmpty())
return;
logger.debug("Removing compaction strategy for pending repair {} on {}.{}", sessionID, cfs.metadata.keyspace, cfs.metadata.name);
strategies = ImmutableMap.copyOf(Maps.filterKeys(strategies, k -> !k.equals(sessionID)));
}
synchronized void removeSSTable(SSTableReader sstable)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Only pass SSTables with a non-null sstable.getSSTableMetadata().pendingRepair into PendingRepairManager
- Re-read sstable metadata to ensure the repair session has not completed and cleared the ID between selection and use
- Route non-repair SSTables to the normal compaction strategy instead
- If hit in stock Cassandra operation, capture nodetool tpstats/repair_admin output and file a bug
Example fix
// before
manager.getScanners(pendingRepairId, sstables);
// after
if (pendingRepairId == null) { regularStrategyScanners(sstables); } else { manager.getScanners(pendingRepairId, sstables); } Defensive patterns
Strategy: type-guard
Validate before calling
if (sstable.getSSTableMetadata().pendingRepair == null)
throw new IllegalArgumentException("sstable " + sstable + " is not pending repair; use regular compaction path"); Type guard
static boolean isPendingRepair(SSTableReader sstable) {
return sstable.getSSTableMetadata().pendingRepair != null;
} Try / catch
try {
manager.getScanners(pendingId, sstables);
} catch (IllegalSSTableArgumentException e) {
// fall back to the default compaction strategy scanners
regularStrategy.getScanners(sstables, null);
} Prevention
- Check sstable metadata pendingRepair before routing to PendingRepairManager
- Re-fetch metadata if time passed since sstable selection (repair may have completed)
- Route non-repair sstables to the standard compaction strategy
- Keep repair sessions alive until all derived compaction work is submitted
When it happens
Trigger: Calling PendingRepairManager.getOrCreate or getScanners with an sstable whose metadata pendingRepair is null (a regular, non-incremental-repair sstable).
Common situations: Custom compaction/repair tooling sending ordinary SSTables into the pending-repair path; race where a repair session finished and promoted/cleared the pendingRepair ID before the call; incremental repair misconfiguration.
Related errors
- You can't compact sstables from different pending repair ses
- Attempting to compact pending repair sstables with sstables
- Prepare phase for incremental repair session %s was unable t
- Unsupported disk access mode for compaction_read_disk_access
- concurrent_compactors should be strictly greater than 0, but
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ad1411a5ca1424d9.
Report an issue: GitHub.