apache/cassandra · error · java.lang.IllegalStateException

No %s operation in progress for %s, can't abort (%s)

Error message

No %s operation in progress for %s, can't abort (%s)

What it means

SingleNodeSequences.abortHelper validates that a decommission/remove/move operation is actually in progress for the requested node before committing a CancelInProgressSequence. If ClusterMetadata contains no matching in-progress sequence, it logs and throws IllegalStateException because there is nothing to abort. This is a state precondition check, not a data corruption issue.

Source

Thrown at src/java/org/apache/cassandra/tcm/sequences/SingleNodeSequences.java:272

            throw new IllegalStateException(String.format("This cluster is migrating to cluster metadata, can't abort %s until that is done.", kind));

        ClusterMetadata metadata = ClusterMetadata.current();
        NodeId toAbort = nodeId == null ? metadata.myNodeId() : NodeId.fromString(nodeId);
        MultiStepOperation<?> sequence = metadata.inProgressSequences.get(toAbort);
        if (sequence == null || sequence.kind() != kind)
        {
            if (toAbort.equals(metadata.myNodeId()) && ssMode != null && StorageService.instance.operationMode() == ssMode)
            {
                // there is no ongoing sequence with the given kind, but storage service operation mode is set, clear it
                logger.debug("There is no ongoing {} sequence for this node, but operation mode is {} - clearing transient mode", kind, ssMode);
                StorageService.instance.clearTransientMode();
                return;
            }
            else
            {
                String msg = String.format("No %s operation in progress for %s, can't abort (%s)", kind, toAbort, sequence);
                logger.info(msg);
                throw new IllegalStateException(msg);
            }
        }
        if (toAbort.equals(metadata.myNodeId()))
        {
            if (ssMode != null && StorageService.instance.operationMode() != ssMode)
            {
                String msg = String.format("Can't abort a %s operation unless it has failed", kind);
                logger.info(msg);
                throw new IllegalStateException(msg);
            }
            StorageService.instance.clearTransientMode();
        }
        else if (Gossiper.instance.isAlive(metadata.directory.endpoint(toAbort)))
        {
            String msg = String.format("Can't abort a %s operation for a node %s (%s) that is UP - run abortdecommission on that instance",
                                       kind, toAbort, metadata.directory.endpoint(toAbort));
            logger.info(msg);
            throw new IllegalStateException(msg);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Verify the in-progress sequence with nodetool / cluster metadata before aborting (check the target node id)
  2. Confirm the operation actually failed - a completed decommission cannot be aborted
  3. Retry with the correct NodeId; use the id from the failed node's logs

Example fix

// before
nodetool abortdecommission 9d7e... (no operation in progress)
// after
// first confirm the in-progress sequence:
nodetool clustermetadata inprogresssequence   // or inspect ClusterMetadata.current().inProgressSequences
nodetool abortdecommission <correctNodeId>
Defensive patterns

Strategy: validation

Validate before calling

// before aborting, confirm an in-progress sequence exists for the node
ClusterMetadata cm = ClusterMetadata.current();
if (!cm.inProgressSequences().anyMatch(s -> s.nodeId().equals(targetNodeId)))
    throw new IllegalStateException("No operation in progress for " + targetNodeId);

Try / catch

try { nodetoolAbortDecommission(nodeId); }
catch (IllegalStateException e) {
    if (e.getMessage().startsWith("No ")) { /* nothing to abort - operation already finished */ }
    else throw e;
}

Prevention

When it happens

Trigger: Calling nodetool abortdecommission / abortremove / abortmove (abortDecommission, abortRemoveNode, abortMove) when no corresponding sequence is registered in ClusterMetadata for the target node, or after the operation already completed/was cancelled.

Common situations: Operator retries an abort command twice; abort issued for the wrong node id; the original operation finished between failure and abort attempt; node id typo.

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


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