apache/cassandra · critical · IllegalStateException
NodeId does not match locally set one. Check for the IP addr
Error message
NodeId does not match locally set one. Check for the IP address collision: %s vs %s %s.
What it means
During non-CMS startup, Startup.initializeAsNonCmsNode verifies with an existing cluster member that the NodeId/HostId the cluster has recorded for this node's broadcast address matches the locally persisted nodeId. On mismatch it throws this IllegalStateException, explicitly warning about a possible IP address collision: two different nodes have claimed (or are claiming) the same broadcast address, or the local hostid file is stale relative to cluster state.
Source
Thrown at src/java/org/apache/cassandra/tcm/Startup.java:245
wrapProcessor,
ClusterMetadataService::state,
logSpec));
ClusterMetadataService.instance().log().ready();
NodeId nodeId = ClusterMetadata.current().myNodeId();
UUID currentHostId = SystemKeyspace.getLocalHostId();
if (nodeId != NodeId.UNREGISTERED && !Objects.equals(nodeId.toUUID(), currentHostId))
{
if (currentHostId == null)
{
logger.info("Taking over the host ID: {}, replacing address {}", nodeId.toUUID(), FBUtilities.getBroadcastAddressAndPort());
SystemKeyspace.setLocalHostId(nodeId.toUUID());
return;
}
String error = String.format("NodeId does not match locally set one. Check for the IP address collision: %s vs %s %s.",
currentHostId, nodeId.toUUID(), FBUtilities.getBroadcastAddressAndPort());
logger.error(error);
throw new IllegalStateException(error);
}
}
/**
* If the broadcast address of this node has changed, we must verify the endpoints it knows for
* the members of the CMS are still reachable and valid. This is necessary for the node to submit
* a STARTUP transformation which updates its broadcast address in ClusterMetadata.
*
* If the node is itself a CMS member, it is also a requirement to be able to contact a
* majority of the other CMS members in order to perform the serial reads and writes which
* constitute committing to and fetching from the distributed metadata log.
*
* To do this, we use a simple protocol:
* 1. For each CMS member in our replayed ClusterMetadata, ping the associated broadcast address
* to query for id of the node at that address. This determines whether the endpoint still
* belongs to that same node (which is/was a CMS member).
* 2. While we don't have confirmed current addresses for a majority of CMS nodes:View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Confirm no other live node holds this broadcast address (nodetool status / system.peers_v2 on a healthy node).
- If this is genuinely a new node on a reused IP, remove the stale cluster registration: decommission the dead node or use cms REMOVENODE for the old hostid.
- Delete the stale local hostid file (hostid.txt in the data directory) only if this node is truly a fresh member, then restart so it registers anew.
- Fix broadcast_address/broadcast_and_listen configuration so the address is unique in the cluster.
- Never edit cluster metadata directly while both nodes are live — take one of them down first.
Example fix
// before: node reuses an address already registered to another hostid cassandra-env: BROADCAST=10.0.0.7 // cluster has 10.0.0.7 -> hostid X, local hostid Y // after: unique address or cleaned registration BROADCAST=10.0.0.42 // or: remove old node (hostid X) before starting this one
Defensive patterns
Strategy: validation
Validate before calling
// before startup, verify no other node claims this IP with a different hostid
UUID local = FBUtilities.getBroadcastAddressAndPort().equals(addr) ? ClusterMetadataService.instance().hostIdFor(addr) : null;
if (local != null && !local.equals(localHostId)) throw new IllegalStateException("Address collision detected"); Try / catch
try { Startup.initializeAsNonCmsNode(...); }
catch (IllegalStateException e) {
if (e.getMessage().contains("IP address collision")) {
// halt startup, alert operator: do NOT delete hostid blindly
failFast(e);
} else throw e;
} Prevention
- Decommission dead nodes before reusing their IPs
- Keep hostid files with their nodes; never copy data dirs between nodes
- Use unique, non-recycled addresses (or clear registrations) in virtualized environments
- Cross-check nodetool status against planned broadcast addresses
When it happens
Trigger: initializeAsNonCmsNode fetches the remote view and finds currentHostId != nodeId.toUUID(); the node's IP was reassigned to different hardware; a stale hostid file persisted locally conflicts with the cluster's registration; the broadcast_address configuration was changed to overlap another node.
Common situations: IP reuse after replacing a node without decommissioning the old one; VM/container IPs recycled between clusters; restored node reusing an old data directory on an address already taken; DNS/hostname resolution pointing multiple nodes at one address.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot move to UNREGISTERED state (%s)
- Could not initialize CMS lookup
- Found no candidates during initialization. Check if the seed
- Cannot replace same address when accord transactions are ena
- Expected to complete startup sequence, but did not. Can't pr
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/eef391f16e9a99af.
Report an issue: GitHub.