apache/cassandra · error · IllegalArgumentException
Another sequence of kind
Error message
Another sequence of kind ${kind} is in progress for node ${nodeIpOrId}. Cannot proceed with move. What it means
finishInProgressSequence resumes an existing MOVE sequence, so it requires that the node's in-progress sequence actually be a MOVE. If inProgressSequences.get(nodeId).kind() is anything else, this IllegalArgumentException is thrown to prevent mixing a token argument with a different operation.
Solutions
- Run the subcommand matching the in-progress sequence kind (e.g. resume/abort the JOIN or REPLACE) instead of move.
- Finish or cancel the other sequence first, then start a fresh MOVE with a --token.
- Verify the node's in-progress sequence kind from the metadata before invoking move.
Example fix
// before bin/cms move -ip 10.0.0.5 --token 1234 // JOIN in progress // after bin/cms <join-resume-or-abort> -ip 10.0.0.5 bin/cms move -ip 10.0.0.5 --token 1234
Defensive patterns
Strategy: validation
Validate before calling
MultiStepOperation<?> op = meta.inProgressSequences.get(nodeId);
if (op != null && op.kind() != MultiStepOperation.Kind.MOVE)
throw new IllegalStateException("Sequence " + op.kind() + " in progress; move cannot resume it"); Try / catch
try { tool.move(nodeId, token); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Cannot proceed with move")) { runMatchingSequenceCommand(); } else throw e; } Prevention
- Match the subcommand to the node's actual in-progress sequence kind.
- List in-progress sequences before resuming any multi-step operation.
- Clear unrelated sequences (JOIN/REPLACE) before starting moves.
When it happens
Trigger: Calling finishInProgressSequence (reached via updatedMetadata) when the node has an in-progress sequence of a non-MOVE kind (JOIN, REPLACE, REBUILD, etc.) while running the move command.
Common situations: Operator confuses an in-progress bootstrap with a move and passes --token; leftover non-MOVE sequence in the metadata snapshot makes the tool think it should resume a move.
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
- Cannot assassinate the node when sequence of kind
- Sequence of kind is in progress for node . Cannot proceed…
- Token required when no MOVE sequence is in progress.
- Can not advance in-progress sequence, since its kind is
- Can not apply in-progress sequence, since its kind is
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/9e3fbaa82ea48da1.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tools/CMSOfflineTool.java:516
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);
}
ClusterMetadata finishInProgressSequence(NodeId nodeId, String token, ClusterMetadata metadata)
{
MultiStepOperation<?> multiStepOperation = metadata.inProgressSequences.get(nodeId);
if (multiStepOperation.kind() != MultiStepOperation.Kind.MOVE)
{
throw new IllegalArgumentException("Another sequence of kind " + multiStepOperation.kind() +
" is in progress for node " + nodeIdentifierOption.getNodeIpOrId() +
". Cannot proceed with move.");
}
Move moveInProgress = (Move) multiStepOperation;
Collection<Token> inProgressTokens = moveInProgress.tokens;
Collection<Token> givenTokenSet;
if (token == null)
{
givenTokenSet = Set.of();
}
else
{
metadata.partitioner.getTokenFactory().validate(token);
givenTokenSet = Set.of(metadata.partitioner.getTokenFactory().fromString(token));
}
if (givenTokenSet.isEmpty() || new HashSet<>(moveInProgress.tokens).equals(givenTokenSet))
{View on GitHub (pinned to 88fd0f6a0e)