apache/cassandra · warning
Versions differ: {} != {}
Error message
Versions differ: {} != {} What it means
WARN log from Directory.dumpDiff(Directory) indicating the versions maps (NodeId to per-node release/feature version) differ between two Directory snapshots. Divergent node versions mean the cluster disagrees on each member's Cassandra version, which gates feature flags and upgrade checks. Diagnostic only; the static dumpDiff also logs per-key value differences.
Source
Thrown at src/java/org/apache/cassandra/tcm/membership/Directory.java:930
logger.warn("Locations differ: {} != {}", locations, other.locations);
}
if (!Objects.equals(states, other.states))
{
logger.warn("States differ: {} != {}", states, other.states);
dumpDiff(logger, states, other.states);
}
if (!Objects.equals(endpointsByDC, other.endpointsByDC))
{
logger.warn("Endpoints by dc differ: {} != {}", endpointsByDC, other.endpointsByDC);
dumpDiff(logger, endpointsByDC.asMap(), other.endpointsByDC.asMap());
}
if (!Objects.equals(racksByDC, other.racksByDC))
{
logger.warn("Racks by dc differ: {} != {}", racksByDC, other.racksByDC);
}
if (!Objects.equals(versions, other.versions))
{
logger.warn("Versions differ: {} != {}", versions, other.versions);
dumpDiff(logger, versions, other.versions);
}
if (!Objects.equals(addresses, other.addresses))
{
logger.warn("Addresses differ: {} != {}", addresses, other.addresses);
dumpDiff(logger, addresses, other.addresses);
}
}
public static <K, V> void dumpDiff(Logger logger, Map<K, V> l, Map<K, V> r)
{
for (K k : Sets.intersection(l.keySet(), r.keySet()))
{
V lv = l.get(k);
V rv = r.get(k);
if (!Objects.equals(lv, rv))
logger.warn("Values for key {} differ: {} != {}", k, lv, rv);
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Complete the rolling upgrade on all nodes so versions converge in cluster metadata
- Replay missed cluster metadata events on the node holding the outdated versions map
- Ensure nodes register their version via the proper TCM transformation rather than local-only state
- Re-diff only snapshots captured at the same epoch
Defensive patterns
Strategy: validation
Validate before calling
// Verify upgrade is complete cluster-wide before diffing version maps
boolean upgradeDone = dir.versions().values().stream()
.allMatch(v -> v.equals(targetVersion));
if (upgradeDone) dir.dumpDiff(other); Prevention
- Finish rolling upgrades on all nodes before making version-dependent assertions
- Ensure node versions are registered via cluster metadata, not local-only state
- Replay metadata on nodes holding outdated version entries
- Snapshot directories at a single epoch for comparisons
When it happens
Trigger: dumpDiff(other) when Objects.equals(versions, other.versions) is false; typically a node upgraded (or its version re-registered via setVersion) in one view while the other view still records the old version.
Common situations: Rolling upgrade in progress with stale metadata on some nodes; a node rejoined with a different binary version; snapshots compared before and after an upgrade transformation was committed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Can't ignore local host %s when doing CMS migration
- nextId differ: {} != {}
- Last modified differ: {} != {}
- Peers differ: {} != {}
- Locations differ: {} != {}
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/7aa622c00148a84e.
Report an issue: GitHub.