apache/cassandra · error · RuntimeException

Attempting to compact pending repair sstables with sstables

Error message

Attempting to compact pending repair sstables with sstables from other repair, or sstables not pending repair: %s

What it means

Cassandra groups SSTables by the incremental-repair session that produced them. Before an incremental compaction runs, getPendingRepair() verifies that every SSTable in the set carries the exact same pendingRepair ID; if the set resolves to zero IDs (non-repair SSTables mixed in) or more than one ID (SSTables from different repair sessions), the compaction is aborted with this RuntimeException.

Source

Thrown at src/java/org/apache/cassandra/db/compaction/CompactionTask.java:462

        for (SSTableReader sstable : actuallyCompact)
            minRepairedAt = Math.min(minRepairedAt, sstable.getSSTableMetadata().repairedAt);
        if (minRepairedAt == Long.MAX_VALUE)
            return ActiveRepairService.UNREPAIRED_SSTABLE;
        return minRepairedAt;
    }

    public static TimeUUID getPendingRepair(Set<SSTableReader> sstables)
    {
        if (sstables.isEmpty())
        {
            return ActiveRepairService.NO_PENDING_REPAIR;
        }
        Set<TimeUUID> ids = new HashSet<>();
        for (SSTableReader sstable: sstables)
            ids.add(sstable.getSSTableMetadata().pendingRepair);

        if (ids.size() != 1)
            throw new RuntimeException(String.format("Attempting to compact pending repair sstables with sstables from other repair, or sstables not pending repair: %s", ids));

        return ids.iterator().next();
    }

    public static boolean getIsTransient(Set<SSTableReader> sstables)
    {
        if (sstables.isEmpty())
        {
            return false;
        }

        boolean isTransient = sstables.iterator().next().isTransient();

        if (!Iterables.all(sstables, sstable -> sstable.isTransient() == isTransient))
        {
            throw new RuntimeException("Attempting to compact transient sstables with non transient sstables");
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Do not compact pending-repair SSTables together with other SSTables; ensure the input set contains only SSTables from a single repair session
  2. Run nodetool repair to completion so pending-repair SSTables are promoted and no longer carry a pendingRepair ID, then compact normally
  3. Check for leaked repair sessions (nodetool listbackups / repair_admin) and cancel stale sessions via RepairRunner or nodetool cancelrepair
  4. If reproducible, report as an incremental-repair bug; this throw indicates an internal invariant violation rather than user error

Example fix

// before: mixing sstables
List<SSTableReader> mixed = Stream.concat(pendingRepairSstables.stream(), regularSstables.stream()).collect(toList());
compactor.compact(mixed);
// after: filter to one repair session
TimeUUID id = pendingRepairSstables.get(0).getSSTableMetadata().pendingRepair;
List<SSTableReader> single = pendingRepairSstables.stream().filter(s -> id.equals(s.getSSTableMetadata().pendingRepair)).collect(toList());
compactor.compact(single);
Defensive patterns

Strategy: validation

Validate before calling

Set<TimeUUID> ids = sstables.stream().map(s -> s.getSSTableMetadata().pendingRepair).collect(Collectors.toSet());
if (ids.size() != 1 || ids.contains(null)) throw new IllegalArgumentException("sstables must all belong to one pending repair session: " + ids);

Prevention

When it happens

Trigger: Calling CompactionManager to compact a set of SSTables where some have sstable metadata pendingRepair=null and others have a pendingRepair ID, or where SSTables come from two different incremental repair sessions.

Common situations: Incremental repair bookkeeping bugs; manually mixing repaired and unrepaired SSTables in a custom compaction; concurrent incremental repair sessions overlapping on the same table; SSTables left over from an aborted repair being compacted together with active-repair SSTables.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/aee6efe07e51053d. Report an issue: GitHub.