apache/cassandra · error · IllegalStateException

Expected to complete startup sequence, but did not. Can't pr

Error message

Expected to complete startup sequence, but did not. Can't proceed from the state 

What it means

Startup.java's resume logic, when finishJoiningRing is true, expects the node to be past its bootstrap/boot-replace phase; if ClusterMetadata still shows the peer (this node) in BOOTSTRAPPING or BOOT_REPLACING state, the invariant 'startup sequence should have completed' is broken and it throws IllegalStateException.

Source

Thrown at src/java/org/apache/cassandra/tcm/Startup.java:703

                {
                    if (DatabaseDescriptor.getAccordTransactionsEnabled())
                    {
                        // TODO (required): we need to support a mode that changes the NodeId when replacing the same address for accord transaction safety
                        throw new IllegalStateException("Cannot replace same address when accord transactions are enabled.");
                    }

                    ReplaceSameAddress.streamData(self, metadata, shouldBootstrap, finishJoiningRing);
                }

                // JOINED appears before BOOTSTRAPPING & BOOT_REPLACE so we can fall
                // through when we start as REGISTERED/LEFT and complete a full startup
                logger.info("{}", StorageService.Mode.NORMAL);
                break;
            case BOOTSTRAPPING:
            case BOOT_REPLACING:
                if (finishJoiningRing)
                {
                    throw new IllegalStateException("Expected to complete startup sequence, but did not. " +
                                                    "Can't proceed from the state " + metadata.directory.peerState(self));
                }
                break;
            case LEAVING:
                logger.info("Node is currently being decommissioned, resume with `nodetool decommission`");
                StorageService.instance.markDecommissionFailed();
                break;
            case MOVING:
                logger.info("Node is currently moving, resume with nodetool move --resume or abort with nodetool move --abort");
                StorageService.instance.markMoveFailed();
                break;
            default:
                throw new IllegalStateException("Can't proceed from the state " + metadata.directory.peerState(self));
        }
    }

    /**
     * Returns:

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Restart with finishJoiningRing=false so the node resumes the in-progress bootstrap/boot-replace sequence
  2. Let the multi-step operation resume via nodetool (or abort it: nodetool abortbootstrap/decommission as appropriate) instead of forcing NORMAL
  3. Inspect ClusterMetadata peer state (nodetool / tcm metadata) to confirm actual state before retrying
  4. Wipe data and re-bootstrap cleanly if the partial bootstrap is unrecoverable

Example fix

// before
Startup.startup(finishJoiningRing = true)
// after
Startup.startup(finishJoiningRing = false) // resume in-progress BOOTSTRAPPING first
Defensive patterns

Strategy: try-catch

Validate before calling

// before forced startup
NodeState s = ClusterMetadata.current().directory.peerState(self);
if ((s == NodeState.BOOTSTRAPPING || s == NodeState.BOOT_REPLACING) && finishJoiningRing)
    finishJoiningRing = false;

Try / catch

try { Startup.startup(...); }
catch (IllegalStateException e) {
    if (e.getMessage().contains("Can't proceed from the state")) {
        // resume with finishJoiningRing=false or abort the in-progress op
    } else throw e;
}

Prevention

When it happens

Trigger: Calling Startup.startup (or StorageService.initServer) with finishJoiningRing=true on a node whose ClusterMetadata peer state is BOOTSTRAPPING or BOOT_REPLACING — i.e. a half-finished bootstrap/replace being resumed as if it were already complete.

Common situations: Interrupted bootstrap (crash or kill mid-join) followed by a restart with flags that force completion of the join ring; automation tools re-running startup with wrong options after a failed 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/cc576eead45f2cdd. Report an issue: GitHub.