apache/cassandra · error · IllegalStateException
Can not commit transformation: "%s"(%s).
Error message
Can not commit transformation: "%s"(%s).
What it means
This is the default failure path of ClusterMetadataService.commit(Transformation): when the commit is rejected, the supplied CommitFailureHandler wraps the rejection code and message in an IllegalStateException. It means the transformation (schema change, topology change, node operation) was not accepted by the metadata log and no callers were registered to handle the failure.
Source
Thrown at src/java/org/apache/cassandra/tcm/ClusterMetadataService.java:637
public final Supplier<Entry.Id> entryIdGen = new Entry.DefaultEntryIdGen();
public interface CommitSuccessHandler<T>
{
T accept(ClusterMetadata latest);
}
public interface CommitFailureHandler<T>
{
T accept(ExceptionCode code, String message);
}
public ClusterMetadata commit(Transformation transform)
{
return commit(transform,
metadata -> metadata,
(code, message) -> {
throw new IllegalStateException(String.format("Can not commit transformation: \"%s\"(%s).",
code, message));
});
}
/**
* Attempt to commit the transformation (with retries).
* <p>
* Since we can not rely on reliability of the network or even the fact that the committing node will stay alive
* for the duration of commit, we have to allow for subsequent discovery of the transformation effects, which can
* be made visible either by replaying the log, or receiving the metadata snapshot.
* <p>
* In other words, there is no reliable way to find out whether _this particular_ transformation has been executed
* while we are allowing replay from snapshot, since even failure response from the CMS does not guarantee
* Paxos re-proposal, which would place the transformation into the log during proposal _by some other_ CMS node.
* <p>
* Protocol does foresee the concept of EntryId that would allow discovery of the committed transformations
* without changes to binary protocol, but this change was left out from the initial implementation of TCM.
* <p>View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Read the embedded rejection code and message in the exception to identify why the transformation was rejected.
- Retry the commit after resolving the conflicting state (e.g. wait for the competing transformation to settle).
- Provide a custom CommitFailureHandler to commit() to handle known rejection codes instead of relying on the throwing default.
- Verify the node is the current CMS leader / can reach the CMS before committing transformations.
- Validate transformation preconditions (e.g. replication params, node states) before calling commit.
Example fix
// before
metadataService.commit(new AddToCMS(...)); // throws raw IllegalStateException on rejection
// after
metadataService.commit(transform,
md -> md,
(code, message) -> {
logger.warn("Commit rejected: {} - {}", code, message);
return RetryResult.retryLater();
}); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate preconditions before commit assert ClusterMetadata.current().schema.getReplicationInfo() != null;
Try / catch
try { service.commit(transform); }
catch (IllegalStateException e) { logger.error("Transformation rejected: {}", e.getMessage()); /* inspect code/message embedded */ } Prevention
- Pass a custom CommitFailureHandler for expected rejections
- Avoid concurrent conflicting topology transformations
- Check CMS leadership before committing
- Validate replication/parameter preconditions up front
When it happens
Trigger: Calling ClusterMetadataService.commit(transformation) (or forceSnapshot) where the transformation fails to commit — e.g. rejected by precondition checks, election lost, conflicting concurrent transformation, or replication/validation failure — with no custom onFailure handler.
Common situations: Concurrent conflicting topology changes (two nodes altering RF or joining simultaneously), schema changes rejected due to invalid replication settings, committing transformations on a node that is not the CMS leader or lost leadership mid-commit, bootstrap/decommission races.
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
- Commits are paused, not trying to commit
- Can't abort bootstrap for - it does not exist in cluster me
- Can't abort bootstrap for since it is not bootstrapping
- Unknown endpoint:
- Unknown endpoint
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4268a31deaca7b6e.
Report an issue: GitHub.