apache/cassandra · error · java.lang.IllegalStateException

No move operation in progress, can't resume

Error message

No move operation in progress, can't resume

What it means

resumeMove requires an in-progress MOVE sequence in ClusterMetadata. If metadata.inProgressSequences has no MOVE for the local node, it throws IllegalStateException 'No move operation in progress, can't resume' - and as a courtesy clears a stale MOVE_FAILED StorageService mode if one is set.

Solutions

  1. Confirm with `nodetool ring` whether the move actually completed - if so, no resume is needed.
  2. Check `nodetool inprogresssequences` for a MOVE entry for this node before resuming.
  3. If StorageService mode was MOVE_FAILED but nothing is in progress, the command already cleared the transient mode; re-run move instead.
  4. Retry the move from scratch if the original one was aborted.

Example fix

// before
nodetool resumemove   // IllegalStateException: no move in progress
// after
nodetool ring          # verify tokens already moved
nodetool move <token>  # start a new move if needed
Defensive patterns

Strategy: validation

Validate before calling

MultiStepOperation<?> seq = ClusterMetadata.current().inProgressSequences.get(self);
if (seq == null || seq.kind() != MultiStepOperation.Kind.MOVE)
    return; // nothing to resume

Type guard

boolean hasMoveInProgress(NodeId self) { MultiStepOperation<?> s = ClusterMetadata.current().inProgressSequences.get(self); return s != null && s.kind() == MultiStepOperation.Kind.MOVE; }

Try / catch

try { resumeMove(); }
catch (IllegalStateException e) { if (e.getMessage().contains("No move operation in progress")) { verifyMoveCompletedOrRestart(); } else throw e; }

Prevention

When it happens

Trigger: Running `nodetool resumemove` when there is no MOVE multi-step operation registered for this node: the move fully completed, was already aborted, or never started on this node.

Common situations: Calling resumemove by mistake on a node where the move succeeded (finishInProgressSequences already ran); resuming after an abort; running the command on the wrong host.

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/e6d713286218bc4b. Report an issue: GitHub.

Appendix: source

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

    static void resumeMove()
    {
        if (ClusterMetadataService.instance().isMigrating() || ClusterMetadataService.state() == ClusterMetadataService.State.GOSSIP)
            throw new IllegalStateException("This cluster is migrating to cluster metadata, can't move until that is done.");

        ClusterMetadata metadata = ClusterMetadata.current();
        NodeId self = metadata.myNodeId();
        MultiStepOperation<?> sequence = metadata.inProgressSequences.get(self);
        if (sequence == null || sequence.kind() != MultiStepOperation.Kind.MOVE)
        {
            String msg = "No move operation in progress, can't resume";
            logger.info(msg);
            if (StorageService.instance.operationMode() == MOVE_FAILED)
            {
                // there is no ongoing move to resume, but operation mode thinks there is
                StorageService.instance.clearTransientMode();
            }
            throw new IllegalStateException(msg);
        }
        if (StorageService.instance.operationMode() != MOVE_FAILED)
        {
            String msg = "Can't resume a move operation unless it has failed";
            logger.info(msg);
            throw new IllegalStateException(msg);
        }
        StorageService.instance.clearTransientMode();
        InProgressSequences.finishInProgressSequences(self);
    }

    static void abortMove(String nodeId)
    {
        abortHelper(nodeId, MultiStepOperation.Kind.MOVE, MOVE_FAILED);
    }

    /**
     *

View on GitHub (pinned to 88fd0f6a0e)