nodetool join
Causes a node that was started with join_ring: false to join the cluster ring.
Synopsis
Section titled “Synopsis”nodetool [connection_options] joinSee connection options for connection options.
Description
Section titled “Description”nodetool join instructs a Cassandra node to join the cluster token ring. This command is only relevant when a node was started with join_ring: false in cassandra.yaml, which prevents automatic ring participation at startup.
Understanding join_ring vs auto_bootstrap
Section titled “Understanding join_ring vs auto_bootstrap”These two settings are often confused but serve different purposes:
| Setting | Purpose | Default |
|---|---|---|
join_ring | Controls whether the node joins the token ring at startup | true |
auto_bootstrap | Controls whether the node streams data when joining | true |
Key distinction:
-
auto_bootstrap: false- The node still joins the cluster automatically at startup, but skips streaming data. The join completes, the node appears innodetool status, and it starts accepting requests immediately (without having the data for its token ranges). -
join_ring: false- The node starts but does NOT join the cluster ring. It connects to seed nodes, participates in gossip to learn cluster topology, but does not appear as a ring member innodetool status. The node waits for an explicitnodetool joincommand before joining.
When to Use
Section titled “When to Use”Scenario 1: Pre-Flight Verification Before Joining
Section titled “Scenario 1: Pre-Flight Verification Before Joining”Start a node without joining to verify everything is correctly configured before committing to the cluster:
# cassandra.yaml on new nodejoin_ring: falseauto_bootstrap: true# 1. Start Cassandra - node runs but doesn't join ringsystemctl start cassandra
# 2. Verify node health and configurationnodetool infonodetool describecluster
# 3. Check connectivity to existing nodesnodetool gossipinfo
# 4. Verify disk space, memory, networkdf -h /var/lib/cassandrafree -m
# 5. Once satisfied, join the ringnodetool join
# 6. Monitor bootstrap progressnodetool netstatsScenario 2: Bulk Loading Data Before Joining
Section titled “Scenario 2: Bulk Loading Data Before Joining”Load data into a node before it joins the ring, avoiding the bootstrap streaming overhead:
join_ring: falseauto_bootstrap: false# 1. Start node (doesn't join ring)systemctl start cassandra
# 2. Load data directly using sstableloader from another node's snapshotsstableloader -d localhost /path/to/snapshot/keyspace/table/
# 3. Once data is loaded, join the ringnodetool join
# 4. Run repair to ensure consistencynodetool repairScenario 3: Replacing a Dead Node with Pre-Staged Data
Section titled “Scenario 3: Replacing a Dead Node with Pre-Staged Data”When replacing a failed node, stage data restoration before joining:
join_ring: falseauto_bootstrap: false# Set the replace address# JVM option: -Dcassandra.replace_address_first_boot=<dead_node_ip># 1. Start nodesystemctl start cassandra
# 2. Restore data from backup# ... restore process ...
# 3. Join the ring to replace the dead nodenodetool join
# 4. Verify node has replaced the dead onenodetool statusScenario 4: Coordinated Multi-Node Expansion
Section titled “Scenario 4: Coordinated Multi-Node Expansion”When adding multiple nodes, start them all first, then join them in a controlled sequence:
# On all new nodesjoin_ring: falseauto_bootstrap: true# 1. Start all new nodes (none join yet)# On node-new-1, node-new-2, node-new-3:systemctl start cassandra
# 2. Verify all nodes are healthyfor node in node-new-1 node-new-2 node-new-3; do ssh $node 'nodetool info'done
# 3. Join nodes one at a time, waiting for each to completessh node-new-1 'nodetool join'# Wait for bootstrap to complete...ssh node-new-1 'nodetool status' # Verify UN status
ssh node-new-2 'nodetool join'# Wait for bootstrap to complete...
ssh node-new-3 'nodetool join'# Wait for bootstrap to complete...Scenario 5: Testing Cluster Connectivity Without Commitment
Section titled “Scenario 5: Testing Cluster Connectivity Without Commitment”Verify a new node can communicate with the cluster without actually joining:
join_ring: false# 1. Start nodesystemctl start cassandra
# 2. Test connectivity and gossipnodetool gossipinfonodetool describecluster
# 3. If tests pass, joinnodetool join
# 4. If tests fail, fix issues and restart without affecting the clustersystemctl stop cassandra# Fix configuration...systemctl start cassandraPrerequisites
Section titled “Prerequisites”For nodetool join to work:
-
Node must be started with
join_ring: falsecassandra.yaml join_ring: false -
Node must not have already joined
- If the node previously joined, the command will fail
-
Node must be able to communicate with the cluster
- Seed nodes must be reachable
- Gossip must be functioning
What Happens When You Run nodetool join
Section titled “What Happens When You Run nodetool join”- Node announces itself to the cluster via gossip
- Token ownership is claimed based on
num_tokensorinitial_token - Node state changes from not-in-ring to JOINING
- Bootstrap begins (if
auto_bootstrap: true)- Data is streamed from existing replicas
- This can take hours for large datasets
- Node state changes to NORMAL when complete
- Node appears in
nodetool statusas UN (Up/Normal) - Node begins accepting client requests
Process Flow
Section titled “Process Flow”Verifying Node State
Section titled “Verifying Node State”Before Join
Section titled “Before Join”# Node should be running but not in ringnodetool info# Look for: "Gossip active: true" but node not in nodetool status
nodetool status# Node should NOT appear in the output yetAfter Join
Section titled “After Join”# Node should now appear in statusnodetool status# Look for the new node with UJ (joining) or UN (normal) status
# Monitor bootstrap progress if auto_bootstrap: truenodetool netstatsCommon Errors
Section titled “Common Errors”"Node is already in the ring"
Section titled “"Node is already in the ring"”Error: Node is already in the ringThe node has already joined, either:
- Automatically at startup (because
join_ringwastrueor defaulted) - Via a previous
nodetool joincommand
Resolution: This is not an error condition if the node is already functioning normally.
"Cannot join ring without local data"
Section titled “"Cannot join ring without local data"”The node is trying to join but has issues with its data directories.
Resolution:
# Check data directory permissions and contentls -la /var/lib/cassandra/data/chown -R cassandra:cassandra /var/lib/cassandra/Node Joins But Bootstrap Fails
Section titled “Node Joins But Bootstrap Fails”If bootstrap fails midway:
# Check bootstrap statusnodetool bootstrap status
# If incomplete, may need to resumenodetool bootstrap resume
# Or check logs for specific errorstail -500 /var/log/cassandra/system.log | grep -i "bootstrap\|stream"Troubleshooting
Section titled “Troubleshooting”Check Current State
Section titled “Check Current State”# Is the node running?nodetool info
# Can it see the cluster?nodetool gossipinfo
# Is it in the ring?nodetool statusCheck Configuration
Section titled “Check Configuration”# Verify join_ring settinggrep join_ring /etc/cassandra/cassandra.yaml
# Verify auto_bootstrap settinggrep auto_bootstrap /etc/cassandra/cassandra.yamlCheck Logs
Section titled “Check Logs”# Look for join-related messagesgrep -i "join\|ring\|bootstrap" /var/log/cassandra/system.log | tail -50Best Practices
Section titled “Best Practices”Join Guidelines
- Verify before joining - Check node health, connectivity, and resources
- Join one node at a time - Never join multiple nodes simultaneously
- Monitor bootstrap - Watch
nodetool netstatsfor streaming progress - Plan for duration - Bootstrap can take hours for large datasets
- Have rollback plan - Know how to decommission if something goes wrong
- Check disk space - Ensure adequate space for streamed data
Important Considerations
- Once joined, the node is part of the cluster—rolling back requires decommission
- If
auto_bootstrap: false, the node will serve requests without having data—run repair immediately - Don't confuse
join_ring: falsewithauto_bootstrap: false—they serve different purposes - The join command has no confirmation prompt—it executes immediately
Comparison: join_ring vs auto_bootstrap
Section titled “Comparison: join_ring vs auto_bootstrap”| Configuration | At Startup | After nodetool join | Data Status | Use Case |
|---|---|---|---|---|
join_ring: true, auto_bootstrap: true | Joins and bootstraps | N/A (already joined) | Has data | Normal new node |
join_ring: true, auto_bootstrap: false | Joins immediately | N/A (already joined) | Empty | Seed nodes, restore from backup |
join_ring: false, auto_bootstrap: true | Waits | Joins and bootstraps | Has data after bootstrap | Pre-flight checks |
join_ring: false, auto_bootstrap: false | Waits | Joins immediately | Empty | Bulk load before join |
Related Commands
Section titled “Related Commands”| Command | Relationship |
|---|---|
| bootstrap | Resume interrupted bootstrap |
| status | Check cluster state and ring membership |
| decommission | Remove node from ring |
| netstats | Monitor streaming during bootstrap |
| gossipinfo | Check gossip state |
| describecluster | View cluster information |