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

  1. Complete the rolling upgrade on all nodes so versions converge in cluster metadata
  2. Replay missed cluster metadata events on the node holding the outdated versions map
  3. Ensure nodes register their version via the proper TCM transformation rather than local-only state
  4. 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

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


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