apache/cassandra · error · java.lang.UnsupportedOperationException
Can not remove a node that has an in-progress sequence
Error message
Can not remove a node that has an in-progress sequence
What it means
SingleNodeSequences.removeNode refuses to remove a node while ClusterMetadata still records an in-progress multi-step sequence (leave/move/decommission/remove) for that node. Thrown as UnsupportedOperationException because concurrent topology operations on the same node are not supported; the previous operation must be finished or aborted first.
Source
Thrown at src/java/org/apache/cassandra/tcm/sequences/SingleNodeSequences.java:145
static void removeNode(NodeId toRemove, boolean force)
{
ClusterMetadata metadata = ClusterMetadata.current();
if (toRemove.equals(metadata.myNodeId()))
throw new UnsupportedOperationException("Cannot remove self");
InetAddressAndPort endpoint = metadata.directory.endpoint(toRemove);
if (endpoint == null)
throw new UnsupportedOperationException("Host ID not found.");
if (Gossiper.instance.getLiveMembers().contains(endpoint))
throw new UnsupportedOperationException("Node " + endpoint + " is alive and owns this ID. Use decommission command to remove it from the ring");
NodeState removeState = metadata.directory.peerState(toRemove);
if (removeState == null)
throw new UnsupportedOperationException("Node to be removed is not a member of the token ring");
if (removeState == NodeState.LEAVING)
logger.warn("Node {} is already leaving or being removed, continuing removal anyway", endpoint);
if (metadata.inProgressSequences.contains(toRemove))
throw new UnsupportedOperationException("Can not remove a node that has an in-progress sequence");
ReconfigureCMS.maybeReconfigureCMS(metadata, endpoint);
logger.info("starting removenode with {} {}", metadata.epoch, toRemove);
Collection<Token> tokens = metadata.tokenMap.tokens(toRemove);
ClusterMetadataService.instance().commit(new PrepareLeave(toRemove,
force,
ClusterMetadataService.instance().placementProvider(),
LeaveStreams.Kind.REMOVENODE));
InProgressSequences.finishInProgressSequences(toRemove);
Gossiper.instance.unsafeBroadcastLeftStatus(endpoint, tokens, metadata.directory.allJoinedEndpoints());
}
static void abortRemoveNode(String nodeId)
{
abortHelper(nodeId, MultiStepOperation.Kind.REMOVE, null);
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Wait for or complete the in-progress sequence (resume/finish the decommission/move) before removing the node.
- Abort the in-progress sequence first, e.g. `nodetool abortdecommission`, `nodetool abortremovenode`, or the matching abort command, then retry removenode.
- Inspect `nodetool inprogresssequences` / ClusterMetadata.inProgressSequences to confirm the node and sequence kind, then choose resume vs abort.
- As a last resort after cluster recovery, verify the sequence is truly stale and clear it via the supported recovery path before re-running removenode.
Example fix
// before nodetool removenode <hostId> // throws: Can not remove a node that has an in-progress sequence // after nodetool abortremovenode <hostId> # or abortdecommission / resume the operation nodetool removenode <hostId>
Defensive patterns
Strategy: validation
Validate before calling
ClusterMetadata md = ClusterMetadata.current();
if (md.inProgressSequences.contains(toRemove))
throw new IllegalStateException("defer removenode: sequence in progress for " + toRemove); Try / catch
try { SingleNodeSequences.removeNode(id, force); }
catch (UnsupportedOperationException e) { /* sequence in progress - resume/abort first, then retry */ } Prevention
- Check inProgressSequences before any removenode call
- Serialize topology operations; never run move/decommission/remove concurrently
- Always abort failed operations before re-issuing them
When it happens
Trigger: Calling `nodetool removenode <hostId>` (which invokes removeNode) while the target node still appears in metadata.inProgressSequences - e.g. a prior decommission, move, or removenode was started but not completed or aborted.
Common situations: Operators retry a failed removenode/decommission without first aborting it; a node crashed mid-decommission leaving the sequence registered; scripted topology changes overlap (move then immediate remove).
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
- This cluster is migrating to cluster metadata, can't move un
- Can not commit transformation: "%s"(%s).
- Unknown endpoint
- Unable to commit rack changes: {r}
- Cannot return topology when accord.enabled = false in cassan
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/1a0ff63bc059e3a5.
Report an issue: GitHub.