apache/cassandra · warning

Could not merge node

Error message

Could not merge node {} to gossip

What it means

When merging a node's state into gossip inside the taskLock-protected block, an unexpected exception during the merge is caught, logged with this warning and the exception, and swallowed so the lock is released and gossip continues. It indicates gossip state for that node was not updated.

Solutions

  1. Read the full stack trace logged with this warning to find the merge failure cause.
  2. Verify cluster version uniformity (run nodetool version everywhere) and complete any interrupted upgrades.
  3. Restart the affected node to re-sync gossip state from peers.
  4. If reproducible, capture the exception and report upstream with the stack trace; check NEWS.txt for known fixes in your release.

Example fix

// before: rolling upgrade with mixed acc-state formats
// after: complete upgrade first
nodetool version  # on every node
nodetool drain && upgrade remaining nodes before heavy acc traffic
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure versions uniform before heavy state churn
boolean uniform = clusterNodes().stream().allMatch(n -> n.getVersion().equals(LOCAL_VERSION));

Try / catch

try { gossiper.merge(nodeId, state); } catch (Exception e) { logger.warn("merge failed for node {}", nodeId, e); /* retry or resync */ }

Prevention

When it happens

Trigger: The state-merge call for a nodeId throws inside the taskLock block (e.g., serialization or state-invariant exceptions) while applying remote endpoint state updates.

Common situations: State mismatches after partial upgrades; concurrent gossip updates racing with node state changes; merge bugs on mixed-version clusters.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/dfea1a0069d17a53. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/gms/Gossiper.java:2411

                            newValue = oldValue;
                    }
                    if (newValue != null)
                    {
                        // note that version needs to be > -1 here, otherwise Gossiper#sendAll on generation change doesn't send it
                        if (!isLocal)
                            newValue = unsafeMakeVersionedValue(newValue.value, oldValue == null ? 0 : oldValue.version);
                        newStates.put(appState, newValue);
                    }
                }
                HeartBeatState heartBeatState = new HeartBeatState(epstate.getHeartBeatState().getGeneration(), isLocal ? VersionGenerator.getNextVersion() : 0);
                EndpointState newepstate = new EndpointState(heartBeatState, newStates);
                unsafeUpdateEpStates(endpoint, newepstate);
                logger.debug("Updated epstates for {}: {}", endpoint, newepstate);
            });
        }
        catch (Exception e)
        {
            logger.warn("Could not merge node {} to gossip", nodeId, e);
        }
        finally
        {
            taskLock.unlock();
        }
    }

    public void triggerRoundWithCMS()
    {
        ClusterMetadata metadata = ClusterMetadata.current();
        Set<InetAddressAndPort> cms = metadata.fullCMSMembers();
        if (!cms.contains(getBroadcastAddressAndPort()))
        {
            logger.debug("Triggering gossip round with CMS {}", metadata.epoch);
            final List<GossipDigest> gDigests = new ArrayList<>();
            Gossiper.instance.makeGossipDigest(gDigests);
            GossipDigestSyn digestSynMessage = new GossipDigestSyn(getClusterName(),
                                                                   getPartitionerName(),

View on GitHub (pinned to 88fd0f6a0e)