apache/cassandra · error · IllegalStateException
Cannot join the ring until bootstrap completes
Error message
Cannot join the ring until bootstrap completes
What it means
A node started in write_survey mode (join_ring=false with bootstrap) collects writes without owning token ranges. joinRing() from this mode is only allowed once bootstrap has completed; otherwise an IllegalStateException is thrown because the node cannot safely take ownership of its range yet.
Solutions
- Wait for bootstrap to complete (watch `nodetool netstats` / bootstrap logs) before calling joinRing
- Verify SystemKeyspace.bootstrapComplete() is true before invoking joinRing
- If the node is stuck, fix the failing bootstrap (streaming errors) and retry
- Restart the node normally if bootstrap was never intended
Example fix
// before
ss.joinRing();
// after
if (SystemKeyspace.bootstrapComplete())
ss.joinRing(); Defensive patterns
Strategy: validation
Validate before calling
if (!SystemKeyspace.bootstrapComplete()) skipJoinRing();
Try / catch
try { ss.joinRing(); } catch (IllegalStateException e) { /* wait for bootstrap, retry later */ } Prevention
- Wait for bootstrap completion before joinRing in write-survey mode
- Monitor nodetool netstats for streaming progress
- Automate join only on bootstrap-complete signal
When it happens
Trigger: Calling StorageService.joinRing() (JMX or API) while isSurveyMode is true and SystemKeyspace.bootstrapComplete() is false.
Common situations: Operator starting a node with -Dcassandra.join_ring=false then calling joinRing before streaming/bootstrap finished; automation that joins the ring too early.
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
- Can't join the ring because in write_survey mode and…
- Not starting client transports in write_survey mode as it's…
- A node required to move the data consistently is down
- A node with address already exists, cancelling join. Use…
- Booting with ClusterMetadata from file:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/eea55e3801fe1f99.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/StorageService.java:1008
}
}
else if (isSurveyMode)
{
// if isSurveyMode then verify the node is in the right state to join the ring
// or that it has already done so
if (ClusterMetadata.current().myNodeState() == JOINED)
{
// note: this has always been a no-op, starting a previously joined node in
// survey mode is meaningless as bootstrapping and joining the ring is already
// complete and a full joined node being restarted in survey mode does not prevent
// it participating in reads. This exists only for backwards compatibilty.
logger.info("Leaving write survey mode and joining ring at operator request");
isSurveyMode = false;
}
else if (!SystemKeyspace.bootstrapComplete())
{
logger.warn("Can't join the ring because in write_survey mode and bootstrap hasn't completed");
throw new IllegalStateException("Cannot join the ring until bootstrap completes");
}
else if (readyToFinishJoiningRing())
{
logger.info("Leaving write survey mode and joining ring at operator request");
exitWriteSurveyMode();
isSurveyMode = false;
daemon.start();
}
else
{
logger.warn("Can't join the ring because in write_survey mode and bootstrap hasn't completed");
throw new IllegalStateException("Cannot join the ring until bootstrap completes");
}
}
else if (isBootstrapMode())
{
// bootstrap is not complete hence node cannot join the ring
logger.warn("Can't join the ring because bootstrap hasn't completed.");View on GitHub (pinned to 88fd0f6a0e)