apache/cassandra · warning
Duplicate host id found: with generation and with…
Error message
Duplicate host id {} found: {} with generation {} and {} with generation {}, keeping the one with the newest generation What it means
GossipHelper.cleanupDuplicateHostIds detects two gossip endpoints claiming the same host ID while building clean endpoint states for TCM metadata conversion. It warns with both endpoints and their gossip generations and keeps the endpoint with the newer generation, discarding the stale one.
Solutions
- Identify which endpoint is genuine (newer generation) and decommission or remove the other from gossip.
- Never clone Cassandra node images; generate a fresh host ID (system.local) for each new node.
- Run nodetool gossipinfo to inspect duplicate host IDs and confirm which IP currently owns the node.
- If the stale entry persists, force-remove it (nodetool remove/assassinate only for truly dead endpoints).
Example fix
// before InetAddressAndPort stale = seenGeneration >= thisGeneration ? endpoint : seenHost; cleanEpstates.remove(stale); // after (already kept by the code: ensure the surviving node has a unique host ID) // regenerate system.local host_id on cloned nodes before joining
Defensive patterns
Strategy: validation
Validate before calling
// Detect duplicate host IDs before conversion
Map<String, List<InetAddressAndPort>> byHostId = new HashMap<>();
epstates.forEach((ep, st) -> {
String id = st.getApplicationState(ApplicationState.HOST_ID).value;
byHostId.computeIfAbsent(id, k -> new ArrayList<>()).add(ep);
});
boolean duplicates = byHostId.values().stream().anyMatch(l -> l.size() > 1); Prevention
- Never clone Cassandra node images or system.local data across nodes.
- Audit host IDs with nodetool gossipinfo after IP changes or restores.
- Decommission nodes properly instead of discarding them.
When it happens
Trigger: Gossip ring contains two InetAddressAndPort entries whose EndpointState share one hostIdString, typically after a node was cloned/imaged or IP reassigned, so two live-looking states carry the same HostID; encountered in fromEndpointStates during gossip-to-TCM conversion.
Common situations: VM/disk images copied without clearing host ID; IP address recycled to a new node while old endpoint state lingers in gossip; restores of node state from backups on different IPs.
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
- Bad NodeState
- Can't abort a operation for a node ( ) that is UP - run…
- Can't commit transformations when running in gossip mode…
- Can't upgrade the first node when STATUS =
- Extracting tokens from
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d31fd193e7c9ec5c.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/compatibility/GossipHelper.java:502
return false;
}
private static Map<InetAddressAndPort, EndpointState> cleanupDuplicateHostIds(Map<InetAddressAndPort, EndpointState> epstates)
{
Map<InetAddressAndPort, EndpointState> cleanEpstates = new HashMap<>();
Map<String, InetAddressAndPort> seenHostIds = new HashMap<>();
for (Map.Entry<InetAddressAndPort, EndpointState> entry : epstates.entrySet())
{
InetAddressAndPort endpoint = entry.getKey();
EndpointState epstate = entry.getValue();
String hostIdString = epstate.getApplicationState(HOST_ID).value;
if (seenHostIds.containsKey(hostIdString))
{
int thisGeneration = epstate.getHeartBeatState().getGeneration();
InetAddressAndPort seenHost = seenHostIds.get(hostIdString);
int seenGeneration = epstates.get(seenHost).getHeartBeatState().getGeneration();
logger.warn("Duplicate host id {} found: {} with generation {} and {} with generation {}, keeping the one with the newest generation",
hostIdString, seenHost, seenGeneration, endpoint, thisGeneration);
if (thisGeneration > seenGeneration)
{
cleanEpstates.remove(seenHost);
cleanEpstates.put(endpoint, epstate);
seenHostIds.put(hostIdString, endpoint);
}
}
else
{
seenHostIds.put(hostIdString, endpoint);
cleanEpstates.put(endpoint, epstate);
}
}
return cleanEpstates;
}
}
View on GitHub (pinned to 88fd0f6a0e)