apache/cassandra · error · IllegalStateException
Failed setting isTransient to %b on %s (isTransient is %b)
Error message
Failed setting isTransient to %b on %s (isTransient is %b)
What it means
The isTransient branch of verifyMetadata: when repair operations set the transient flag on an sstable (used by repaired-data tracking and incremental repair with transient repairs), the code verifies sstable.isTransient() afterwards and throws IllegalStateException if the flag does not equal the requested value. The transient metadata write failed or was overwritten concurrently.
Source
Thrown at src/java/org/apache/cassandra/db/compaction/CompactionStrategyManager.java:1537
// if there was an exception mutating repairedAt, we should still notify for the
// sstables that we were able to modify successfully before releasing the lock
cfs.getTracker().notifySSTableRepairedStatusChanged(changed);
}
finally
{
writeLock.unlock();
}
}
}
private static void verifyMetadata(SSTableReader sstable, long repairedAt, TimeUUID pendingRepair, boolean isTransient)
{
if (!Objects.equals(pendingRepair, sstable.getPendingRepair()))
throw new IllegalStateException(String.format("Failed setting pending repair to %s on %s (pending repair is %s)", pendingRepair, sstable, sstable.getPendingRepair()));
if (repairedAt != sstable.getRepairedAt())
throw new IllegalStateException(String.format("Failed setting repairedAt to %d on %s (repairedAt is %d)", repairedAt, sstable, sstable.getRepairedAt()));
if (isTransient != sstable.isTransient())
throw new IllegalStateException(String.format("Failed setting isTransient to %b on %s (isTransient is %b)", isTransient, sstable, sstable.isTransient()));
}
public CleanupSummary releaseRepairData(Collection<TimeUUID> sessions)
{
List<CleanupTask> cleanupTasks = new ArrayList<>();
readLock.lock();
try
{
for (PendingRepairManager prm : Iterables.concat(pendingRepairs.getManagers(), transientRepairs.getManagers()))
cleanupTasks.add(prm.releaseSessionData(sessions));
}
finally
{
readLock.unlock();
}
CleanupSummary summary = new CleanupSummary(cfs, Collections.emptySet(), Collections.emptySet());
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Re-run the repair (transient flag will be set again in a consistent pass)
- Retry after in-flight compactions/repairs on the table settle
- Avoid concurrent repairs and user-defined compactions during transient repair finalization
- If reproducible without concurrency, file a Cassandra bug including sstablemetadata for the sstable
Defensive patterns
Strategy: try-catch
Validate before calling
boolean current = sstable.isTransient(); if (current == desiredIsTransient) return; // nothing to mutate, skip verification path
Try / catch
try { mutateTransientAndVerify(sstable, isTransient); }
catch (IllegalStateException e) {
logger.warn("transient flag race on {} - repair will retry", sstable, e);
} Prevention
- Do not interleave transient repair with user-defined compaction on the same sstables
- Check sstable.isTransient() before mutating to avoid redundant writes
- Ensure transient repair finalization runs under the compaction strategy read lock
- Re-run repair after any transient metadata verification failure
When it happens
Trigger: mutateRepaired(..., isTransient) invoked during transient/incremental repair transitions (promote or demote of transient sstables) with a concurrent sstable lifecycle operation changing isTransient before verification.
Common situations: Transient repair racing with compaction that merges transient sstables into non-transient output; concurrent repair finalization; tooling toggling transient state while repair runs.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed setting pending repair to %s on %s (pending repair is
- Failed setting repairedAt to %d on %s (repairedAt is %d)
- Could not reference sstables
- Maximum pool size has been changed while resizing
- repair_session_max_tree_depth should not be < 10, but was ${
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/e07157cc230e3698.
Report an issue: GitHub.