apache/cassandra · error · IllegalStateException
Can't unregister node(s):
Error message
Can't unregister node(s):
What it means
Thrown by CMSOperations.unregisterLeftNodes when one or more nodes cannot be unregistered because their current NodeState does not permit it. The message lists each node with a state-specific remediation hint.
Solutions
- Inspect the reported per-node messages: wait until the leave operation completes, then retry.
- Complete or abort any in-progress decommission/leave for the blocking nodes.
- Verify each node's NodeState via cluster metadata before re-running unregister.
Example fix
// before nodetool unregister nodeA nodeB // nodeB still LEAVING // after # wait for nodeB decommission to finish, then: nodetool unregister nodeA nodeB
Defensive patterns
Strategy: validation
Validate before calling
for (NodeId id : nodeIds) { NodeState st = ClusterMetadata.current().plan.get(id).state(); if (st != NodeState.LEFT) throw new IllegalStateException(id + " not LEFT yet (" + st + "); wait for leave to complete"); } Try / catch
try { ops.unregisterLeftNodes(nodeIds); } catch (IllegalStateException e) { logger.warn("Unregister deferred: {}", e.getMessage()); } Prevention
- Wait for decommission completion before unregister
- Unregister one node at a time to isolate blocking states
- Read per-node remediation hints in the error message
When it happens
Trigger: Calling unregisterLeftNodes with node ids whose cluster metadata state is not LEFT (e.g. still LEAVING, decommission in progress, or in some other non-removable state).
Common situations: Running nodetool unregister on nodes whose decommission has not finished, batch-unregistering nodes where one is mid-leave, or retrying too soon after a failed decommission.
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
- Can not advance in-progress sequence, since its kind is
- Can not apply in-progress sequence, since its kind is
- Addresses differ: !=
- Bad CMS state:
- Bad NodeState
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/659e5efc3803bde6.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/CMSOperations.java:348
switch (nodeState)
{
case REGISTERED:
case BOOTSTRAPPING:
case BOOT_REPLACING:
message.append(" - need to use `nodetool abortbootstrap` instead of unregistering").append('\n');
break;
case JOINED:
message.append(" - use `nodetool decommission` or `nodetool removenode` to remove this node").append('\n');
break;
case MOVING:
message.append(" - wait until move has been completed, then use `nodetool decommission` or `nodetool removenode` to remove this node").append('\n');
break;
case LEAVING:
message.append(" - wait until leave-operation has completed, then retry this command").append('\n');
break;
}
}
throw new IllegalStateException("Can't unregister node(s):\n" + message);
}
for (NodeId nodeId : nodeIds)
{
logger.info("Unregistering " + nodeId);
cms.commit(new Unregister(nodeId, EnumSet.of(NodeState.LEFT), ClusterMetadataService.instance().placementProvider()));
}
}
public Map<Long, Map<String, String>> dumpDirectory(boolean tokens)
{
Map<Long, Map<String, Object>> directory = ClusterMetadataDirectoryTable.directory(tokens);
return convertToStringValues(directory);
}
public Map<Long, Map<String, String>> dumpLog(long startEpoch, long endEpoch)
{
Map<Long, Map<String, Object>> log = ClusterMetadataLogTable.log(startEpoch, endEpoch);View on GitHub (pinned to 88fd0f6a0e)