apache/cassandra · error · IllegalArgumentException

Token required when no MOVE sequence is in progress.

Error message

Token required when no MOVE sequence is in progress.

What it means

The move operation can either finish an in-progress MOVE sequence (using its tokens) or start a new move, which requires an explicit target token. When no MOVE is in progress and no --token was supplied, this IllegalArgumentException is thrown because there is nothing to move to.

Solutions

  1. Re-run the command with a target token, e.g. `cms move -ip <ip> --token <token>`.
  2. If a MOVE was expected to be in progress, check metadata.inProgressSequences for the node and resume with the correct subcommand.
  3. Validate the token is within the partitioner range before retrying.

Example fix

// before
bin/cms move -ip 10.0.0.5
// after
bin/cms move -ip 10.0.0.5 --token 3074457345618258602
Defensive patterns

Strategy: validation

Validate before calling

if (!hasMoveInProgress(meta, nodeId) && token == null)
    throw new IllegalArgumentException("--token is required when no MOVE sequence is in progress for " + nodeId);

Try / catch

try { tool.move(nodeId, null); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Token required")) { retryWithToken(); } else throw e; }

Prevention

When it happens

Trigger: Running the move subcommand in `execute` when metadata.inProgressSequences.get(nodeId) is not a MOVE (or absent) and the `token` argument is null.

Common situations: Operator forgets the --token flag when moving a node; operator assumed a MOVE was still in progress (from a previous interrupted run) but the metadata shows it completed or was cancelled.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/tools/CMSOfflineTool.java:491

        private String outputFilePath;

        @Override
        protected void execute(Output output) throws IOException
        {
            // Took the reference from org.apache.cassandra.tcm.sequences.SingleNodeSequences.move
            ClusterMetadata metadata = parseClusterMetadata();
            NodeId nodeId = nodeIdentifierOption.getNodeId(metadata);

            if (metadata.inProgressSequences.contains(nodeId))
            {
                ClusterMetadata updatedMetadata = finishInProgressSequence(nodeId, token, metadata);
                writeMetadata(output, updatedMetadata, outputFilePath);
                return;
            }

            if (null == token)
            {
                throw new IllegalArgumentException("Token required when no MOVE sequence is in progress.");
            }
            metadata.partitioner.getTokenFactory().validate(token);
            Token toToken = metadata.partitioner.getTokenFactory().fromString(token);
            if (metadata.tokenMap.tokens().contains(toToken))
            {
                NodeId tokenOwnerId = metadata.tokenMap.owner(toToken);
                throw new IllegalArgumentException("Target token " + toToken + " is already owned by node " + tokenOwnerId.id());
            }
            if (metadata.tokenMap.tokens(nodeId).size() > 1)
            {
                throw new UnsupportedOperationException("This node has more than one token and cannot be moved thusly.");
            }

            PrepareMove prepareMove = new PrepareMove(nodeId, Set.of(toToken), new UniformRangePlacement(), false);
            ClusterMetadata updatedMetadata = prepareMove.execute(metadata).success().metadata;
            updatedMetadata = updatedMetadata.inProgressSequences.get(nodeId).applyTo(updatedMetadata).success().metadata;
            writeMetadata(output, updatedMetadata, outputFilePath);
        }

View on GitHub (pinned to 88fd0f6a0e)