apache/cassandra · warning

nextId differ: {} != {}

Error message

nextId differ: {} != {}

What it means

This is a diagnostic WARN log emitted by Directory.dumpDiff(Directory), not a thrown exception. It fires when two Directory snapshots being compared disagree on the nextId field, the allocator counter used to assign fresh NodeIds to cluster members. Divergent nextId means the two cluster views have processed different membership-changing transformations and are no longer equivalent.

Source

Thrown at src/java/org/apache/cassandra/tcm/membership/Directory.java:899

    {
        return nextId == directory.nextId &&
               Objects.equals(peers, directory.peers) &&
               Objects.equals(locations, directory.locations) &&
               Objects.equals(states, directory.states) &&
               Objects.equals(endpointsByDC, directory.endpointsByDC) &&
               Objects.equals(racksByDC, directory.racksByDC) &&
               Objects.equals(versions, directory.versions) &&
               Objects.equals(addresses, directory.addresses) &&
               Objects.equals(removedNodes, directory.removedNodes);
    }
    
    private static final Logger logger = LoggerFactory.getLogger(Directory.class);

    public void dumpDiff(Directory other)
    {
        if (nextId != other.nextId)
        {
            logger.warn("nextId differ: {} != {}", nextId, other.nextId);
        }
        if (!Objects.equals(lastModified, other.lastModified))
        {
            logger.warn("Last modified differ: {} != {}", lastModified, other.lastModified);
        }
        if (!Objects.equals(peers, other.peers))
        {
            logger.warn("Peers differ: {} != {}", peers, other.peers);
            dumpDiff(logger, peers, other.peers);
        }
        if (!Objects.equals(locations, other.locations))
        {
            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);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Compare the transformation logs of both cluster members and replay the missed cluster metadata events on the diverging node so its Directory catches up to the same epoch
  2. Verify both nodes read from the same CMS (ClusterMetadataService) and are not partitioned into separate quorums
  3. If the diff is expected (e.g. snapshot taken at different epochs), compare snapshots at the same epoch before diffing
  4. Report to the Cassandra community if the divergence is reproducible without a partition, as it may indicate a missed-write bug in TCM replication

Example fix

// before: diffing snapshots from different epochs
if (!thisDir.equivalentTo(otherDir)) thisDir.dumpDiff(otherDir);
// after: only diff snapshots taken at the same epoch
if (thisDir.lastModified().equals(otherDir.lastModified()) && !thisDir.equivalentTo(otherDir))
    thisDir.dumpDiff(otherDir);
Defensive patterns

Strategy: validation

Validate before calling

// Before diffing, confirm both snapshots are from the same point in metadata history
if (thisDir.lastModified().equals(otherDir.lastModified()) && !thisDir.equivalentTo(otherDir)) {
    thisDir.dumpDiff(otherDir); // differences are then meaningful
}

Type guard

boolean comparableSnapshots(Directory a, Directory b) {
    return a != null && b != null && a.lastModified().equals(b.lastModified());
}

Prevention

When it happens

Trigger: Calling directory.dumpDiff(other) on two Directory instances whose nextId counters differ; typically invoked after equivalence checks fail during cluster reconciliation, CMS consistency debugging, or reproducing a Directory from serialized state.

Common situations: Operators diffing the CMS directory across nodes after a metadata divergence; developers running TCM dtests where two replicas applied different sequences of Bootstrap/Decommission transformations; a node that missed part of the cluster metadata log and rebuilt its Directory from a stale snapshot.

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/2714c9ce90d53bd4. Report an issue: GitHub.