apache/cassandra · error · IllegalStateException
Cluster is not running unsafe TCM mode, can't revert epoch
Error message
Cluster is not running unsafe TCM mode, can't revert epoch
What it means
Thrown by CMSOperations.unsafeRevertClusterMetadata when reverting cluster metadata to an earlier epoch is requested while the unsafe TCM mode flag is disabled. Unsafe mode is an explicit opt-in that permits destructive metadata rollback operations.
Solutions
- Set unsafe_tcm_mode: true in cassandra.yaml and restart the node, then retry the revert.
- Confirm with the Cassandra documentation that metadata rollback is required before enabling the flag.
- After the revert completes, disable unsafe_tcm_mode again.
Example fix
// before (cassandra.yaml) # unsafe_tcm_mode not set // after unsafe_tcm_mode: true
Defensive patterns
Strategy: validation
Validate before calling
if (!DatabaseDescriptor.getUnsafeTCMMode()) throw new IllegalStateException("Enable unsafe_tcm_mode and restart before reverting epochs"); Try / catch
try { ops.unsafeRevertClusterMetadata(epoch); } catch (IllegalStateException e) { logger.error("Revert rejected: {}", e.getMessage()); } Prevention
- Enable unsafe_tcm_mode in cassandra.yaml before rollback operations
- Remember a node restart is needed for config changes
- Disable unsafe mode again after recovery
When it happens
Trigger: Calling unsafeRevertClusterMetadata(long epoch) (e.g. via nodetool) when DatabaseDescriptor.getUnsafeTCMMode() returns false.
Common situations: Operator tries to roll back metadata after a failed upgrade without having enabled unsafe_tcm_mode in cassandra.yaml, or forgets to restart the node after setting it.
Related errors
- Cluster is not running unsafe TCM mode, can't load cluster…
- A repair_session_space of
- accord.journal_directory must not be the same as the…
- Accord journal is configured in periodic mode, while…
- accord.working_set_size option was set incorrectly to
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/9c3581f111ca9550.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/CMSOperations.java:268
info.put(COMMITS_PAUSED, Boolean.toString(cms.commitsPaused()));
info.put(REPLICATION_FACTOR, metadata.epoch.isBefore(Epoch.FIRST) ? "" : ReplicationParams.meta(metadata).toString());
info.put(CMS_ID, Integer.toString(metadata.metadataIdentifier));
return info;
}
@Override
public void snapshotClusterMetadata()
{
logger.info("Triggering cluster metadata snapshot");
Epoch epoch = cms.triggerSnapshot().epoch;
logger.info("Cluster metadata snapshot triggered at {}", epoch);
}
@Override
public void unsafeRevertClusterMetadata(long epoch)
{
if (!DatabaseDescriptor.getUnsafeTCMMode())
throw new IllegalStateException("Cluster is not running unsafe TCM mode, can't revert epoch");
cms.revertToEpoch(Epoch.create(epoch));
}
@Override
public String dumpClusterMetadata(long epoch, long transformToEpoch, String version) throws IOException
{
return cms.dumpClusterMetadata(Epoch.create(epoch), Epoch.create(transformToEpoch), Version.valueOf(version));
}
@Override
public String dumpClusterMetadata() throws IOException
{
return dumpClusterMetadata(Epoch.EMPTY.getEpoch(),
ClusterMetadata.current().epoch.getEpoch() + 1000,
NodeVersion.CURRENT.serializationVersion().toString());
}
@OverrideView on GitHub (pinned to 88fd0f6a0e)