apache/cassandra · error · IllegalArgumentException

Cannot assassinate the node when sequence of kind

Error message

Cannot assassinate the node when sequence of kind ${sequenceKind} is in progress. Run abortbootstrap instead.

What it means

The assassinate (force-remove) path of CMSOfflineTool refuses to run when the target node has a JOIN or REPLACE sequence in progress, since those are handled by the dedicated abortbootstrap command. Throwing this IllegalArgumentException steers the operator to the correct tool.

Solutions

  1. Run `abortbootstrap` for the node first to clear the JOIN/REPLACE sequence, then retry assassinate.
  2. Bring the node back and let the join/replace complete, then decommission normally.
  3. If abortbootstrap is unavailable offline, restore the cluster and use the online cms/ndtool abort flow.

Example fix

// before
bin/cms assassinate <ip>
// after
bin/nodetool abortbootstrap <ip>   # or cms abortbootstrap
bin/cms assassinate <ip>
Defensive patterns

Strategy: validation

Validate before calling

MultiStepOperation<?> op = meta.inProgressSequences.get(nodeId);
if (op != null && (op.kind() == MultiStepOperation.Kind.JOIN || op.kind() == MultiStepOperation.Kind.REPLACE))
    throw new IllegalStateException("Use abortbootstrap for kind " + op.kind() + " instead of assassinate");

Try / catch

try { tool.assassinate(nodeId); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Run abortbootstrap")) { runAbortBootstrap(nodeId); } else throw e; }

Prevention

When it happens

Trigger: Calling the assassinate operation in `execute` when metadata.inProgressSequences.get(nodeId) is non-null and its kind() equals MultiStepOperation.Kind.JOIN or Kind.REPLACE (i.e. not in supportedCancelSequences).

Common situations: Operator tries to force-remove a node that was mid-bootstrap or mid-replace when the cluster went down; normal decommission failed and the operator reaches for assassinate without first aborting the bootstrap.

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

Appendix: source

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

        private String outputFilePath;

        @Override
        protected void execute(Output output) throws IOException
        {
            ClusterMetadata metadata = parseClusterMetadata();
            NodeId nodeId = nodeIdentifierOption.getNodeId(metadata);

            // Check if there are any in-progress sequences for given node
            // If any, then cancel the sequence and then assassinate it
            if (metadata.inProgressSequences.contains(nodeId))
            {
                MultiStepOperation<?> multiStepOperation = metadata.inProgressSequences.get(nodeId);
                MultiStepOperation.Kind sequenceKind = multiStepOperation.kind();
                if (!supportedCancelSequences.contains(sequenceKind))
                {
                    if (sequenceKind == MultiStepOperation.Kind.JOIN || sequenceKind == MultiStepOperation.Kind.REPLACE)
                    {
                        throw new IllegalArgumentException("Cannot assassinate the node when sequence of kind " +
                                                           sequenceKind + " is in progress. " +
                                                           "Run abortbootstrap instead.");
                    }
                    else
                    {
                        throw new IllegalArgumentException("Cannot assassinate the node when sequence of kind " +
                                                           sequenceKind + " is in progress.");
                    }
                }

                output.out.printf("Cancelling in-progress sequence of kind %s before assassinating node.\n",
                                  metadata.inProgressSequences.get(nodeId).kind());
                metadata = new CancelInProgressSequence(nodeId).execute(metadata).success().metadata;
            }

            metadata = maybeReconfigureCMS(metadata, nodeId);
            Assassinate transformation = new Assassinate(nodeId, ClusterMetadataService.instance().placementProvider());
            ClusterMetadata updatedMetadata = transformation.execute(metadata).success().metadata;

View on GitHub (pinned to 88fd0f6a0e)