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

  1. Read the embedded rejection code and message in the exception to identify why the transformation was rejected.
  2. Retry the commit after resolving the conflicting state (e.g. wait for the competing transformation to settle).
  3. Provide a custom CommitFailureHandler to commit() to handle known rejection codes instead of relying on the throwing default.
  4. Verify the node is the current CMS leader / can reach the CMS before committing transformations.
  5. 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

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


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