apache/cassandra · error · UnsupportedOperationException
Node in state; wait for status to become normal
Error message
Node in state; wait for status to become normal
What it means
decommission checks StorageService.instance.operationMode() and only permits LEAVING, NORMAL, or DECOMMISSION_FAILED. If the node is in any other mode (e.g. BOOTSTRAP, JOINING, STARTING, or mid-rebuild), it throws this UnsupportedOperationException. The message interpolates the current mode.
Source
Thrown at src/java/org/apache/cassandra/tcm/sequences/SingleNodeSequences.java:75
Logger logger = LoggerFactory.getLogger(SingleNodeSequences.class);
/**
* Entrypoint to begin node decommission process.
*
* @param shutdownNetworking if set to true, will also shut down networking on completion
* @param force if set to true, will decommission the node even if this would mean there will be not enough nodes
* to satisfy replication factor
*/
static void decommission(boolean shutdownNetworking, boolean force)
{
if (ClusterMetadataService.instance().isMigrating() || ClusterMetadataService.state() == ClusterMetadataService.State.GOSSIP)
throw new IllegalStateException("This cluster is migrating to cluster metadata, can't decommission until that is done.");
ClusterMetadata metadata = ClusterMetadata.current();
StorageService.Mode mode = StorageService.instance.operationMode();
if (!EnumSet.of(LEAVING, NORMAL, DECOMMISSION_FAILED).contains(mode))
throw new UnsupportedOperationException("Node in " + mode + " state; wait for status to become normal");
logger.debug("DECOMMISSIONING");
NodeId self = metadata.myNodeId();
Collection<Token> tokens = metadata.tokenMap.tokens(self);
ReconfigureCMS.maybeReconfigureCMS(metadata, getBroadcastAddressAndPort());
MultiStepOperation<?> inProgress = metadata.inProgressSequences.get(self);
if (inProgress == null)
{
logger.info("starting decommission with {} {}", metadata.epoch, self);
// We reset transferred ranges upon starting a decommission so that we fully stream
// anything written since a previous attempt which may not have been persisted to a pending endpoint
SystemKeyspace.resetTransferredRanges();
logger.info("done resetting transferred ranges {} {}", metadata.epoch, self);
ClusterMetadataService.instance().commit(new PrepareLeave(self,
force,
ClusterMetadataService.instance().placementProvider(),
LeaveStreams.Kind.UNBOOTSTRAP),View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Wait until `nodetool status` / logs show the node is in NORMAL state, then retry decommission.
- If stuck in DECOMMISSION_FAILED, decommission is allowed — retry it to resume/finish.
- If a join/bootstrap is genuinely in progress, complete or abort it first.
- After a crash, restart the node so it settles into NORMAL before decommissioning.
Example fix
// before
nodetool decommission // node still JOINING
// after
// guard before calling
if (StorageService.instance.operationMode() == StorageService.Mode.NORMAL) {
nodetool.decommission();
} Defensive patterns
Strategy: validation
Validate before calling
StorageService.Mode mode = StorageService.instance.operationMode();
if (!EnumSet.of(Mode.LEAVING, Mode.NORMAL, Mode.DECOMMISSION_FAILED).contains(mode)) {
throw new RuntimeException("Node in " + mode + " state; decommission not allowed yet");
} Try / catch
try {
decommission();
} catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Node in ") && e.getMessage().contains("wait for status")) {
waitForMode(StorageService.Mode.NORMAL);
decommission();
} else throw e;
} Prevention
- Check `nodetool status` / operation mode shows NORMAL before decommissioning.
- Script maintenance to wait for node readiness after startup.
- Handle DECOMMISSION_FAILED by simply retrying decommission.
- Avoid issuing topology commands concurrently from multiple operators.
When it happens
Trigger: Calling decommission while the node's operation mode is not NORMAL/LEAVING/DECOMMISSION_FAILED — e.g. the node is still joining, bootstrapping, or recovering from a failed decommission in another state.
Common situations: Operator runs decommission too soon after node start before status is NORMAL; a previous bootstrap or join is still in flight; a stuck prior operation left the node in a non-normal mode.
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 decommi
- Cannot alter RF while some endpoints are not in normal state
- Unable to find sufficient sources for streaming range " + tr
- Allocated token %s already assigned to node %s. Is another n
- Snitch definitions at %s do not define a location for this n
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/227427abb4af077e.
Report an issue: GitHub.