apache/cassandra · warning
Could not find NodeId for endpoint
Error message
Could not find NodeId for endpoint {} What it means
Warning logged by GossipCMSListener.onJoin when gossip delivers state for an endpoint that has no corresponding NodeId in the ClusterMetadata directory. The listener cannot correlate the gossiping node with TCM membership, so it returns early and ignores the endpoint's state (e.g. an IP change cannot be applied).
Solutions
- If the node was decommissioned, fully stop it and remove it from gossip (nodetool assassinate only as a last resort) so its stale state stops arriving
- If the node should be a member, re-bootstrap it properly through the CMS so it gets a NodeId registered in the directory
- Verify the node's cluster name and seeds configuration — a node from a different cluster must not be allowed to gossip into this one
Defensive patterns
Strategy: validation
Validate before calling
NodeId nodeId = metadata.directory.nodeIdFromHostId(hostId);
if (nodeId == null) {
// endpoint unknown to CMS: stop processing gossip state for it
logger.warn("Unknown endpoint {} - not registered with CMS", endpoint);
return;
} Prevention
- Fully stop decommissioned nodes so they stop gossiping
- Verify cluster name and seed configuration on all joining nodes
- After failed migrations, verify directory membership matches gossip membership before resuming
When it happens
Trigger: onJoin (via onAlive) reads the hostId gossip application state, calls metadata.directory.nodeIdFromHostId(hostId), and gets null — the endpoint/host ID is unknown to the CMS directory. Called by onAlive when a previously down node comes back or a new node joins via gossip.
Common situations: A node rejoining after being removed from the directory (decommissioned) but still gossiping; gossip and TCM membership out of sync after a failed migration/upgrade; a foreign node from another cluster misconfigured with this cluster name joining gossip; stale gossip state on a restarted node.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Host ID collision for
- A node with address already exists, cancelling join. Use…
- Bad NodeState
- broadcast_address cannot be a wildcard address (
- Can't abort a operation for a node ( ) that is UP - run…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/69ea3b26c9088fca.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/migration/GossipCMSListener.java:75
if (Gossiper.isHibernate(epState))
return;
if (hostIdValue != null)
{
UUID hostId = UUID.fromString(hostIdValue.value);
nodeId = metadata.directory.nodeIdFromHostId(hostId);
InetAddressAndPort oldEndpoint = metadata.directory.endpoint(nodeId);
if (Gossiper.instance.compareEndpointStartup(oldEndpoint, endpoint) > 0)
{
logger.warn("Host ID collision for {} between {} and {}; ignored {}", hostId, oldEndpoint, endpoint, endpoint);
return;
}
logger.info("Node {} (hostId = {}) changing IP from {} to {}", nodeId, hostId, oldEndpoint, endpoint);
Gossiper.instance.removeEndpoint(oldEndpoint);
}
else
{
logger.warn("Could not find NodeId for endpoint {}", endpoint);
return;
}
}
// only thing that can change is the release version and addresses
CassandraVersion gossipVersion = epState.getReleaseVersion();
NodeAddresses newAddresses = GossipHelper.getAddressesFromEndpointState(endpoint, epState);
while (true)
{
NodeVersion cmVersion = metadata.directory.versions.get(nodeId);
if (cmVersion.cassandraVersion.equals(gossipVersion) && newAddresses.equals(metadata.directory.getNodeAddresses(nodeId)))
{
return;
}
else
{
ClusterMetadata.Transformer transformer = metadata.transformer();
if (gossipVersion != null && !cmVersion.cassandraVersion.equals(gossipVersion))
transformer = transformer.withVersion(nodeId, NodeVersion.fromCassandraVersion(gossipVersion));View on GitHub (pinned to 88fd0f6a0e)