apache/cassandra · critical · CMSIdentifierMismatchException

Cluster Metadata Identifier mismatch. Node is attempting to

Error message

Cluster Metadata Identifier mismatch. Node is attempting to communicate with a node from a different cluster. Current identifier %d. Remote identifier: %d

What it means

When validating metadata exchanged with a peer, the node compares its current ClusterMetadata identifier against the remote one. A remote identifier equal to the sentinel EMPTY_METADATA_IDENTIFIER is tolerated (peer hasn't finished joining CMS), but any other mismatch means the two nodes belong to different logical clusters, and CMSIdentifierMismatchException is thrown to prevent cross-cluster communication.

Source

Thrown at src/java/org/apache/cassandra/tcm/ClusterMetadata.java:1305

        return ClusterMetadataService.instance().metadata();
    }

    public static void checkIdentifier(int remoteIdentifier)
    {
        ClusterMetadata metadata = currentNullable();
        if (metadata != null)
        {
            int currentIdentifier = metadata.metadataIdentifier;
            // We haven't yet joined CMS fully
            if (currentIdentifier == EMPTY_METADATA_IDENTIFIER)
                return;

            // Peer hasn't yet joined CMS fully
            if (remoteIdentifier == EMPTY_METADATA_IDENTIFIER)
                return;

            if (currentIdentifier != remoteIdentifier)
                throw new CMSIdentifierMismatchException(String.format("Cluster Metadata Identifier mismatch. Node is attempting to communicate with a node from a different cluster. Current identifier %d. Remote identifier: %d", currentIdentifier, remoteIdentifier));
        }
    }

    /**
     * Startup of some services may race with cluster metadata initialization. We allow those services to
     * gracefully handle scenarios when it is not yet initialized.
     */
    public static ClusterMetadata currentNullable()
    {
        ClusterMetadataService service = ClusterMetadataService.instance();
        if (service == null)
            return null;
        return service.metadata();
    }

    public NodeId myNodeId()
    {
        return localNodeId;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Verify both nodes' cluster metadata identifiers match (logs show current vs remote).
  2. If the node was cloned/restored from another cluster, re-bootstrap it correctly into the intended cluster.
  3. Fix seed/contact configuration so nodes join the correct cluster.
  4. Never reuse a data directory or commit log from a different cluster without cleaning TCM state.

Example fix

// before
// node joined with stale seed from another cluster
seed_provider: [{seeds: "10.0.0.5:7000"}] // wrong cluster
// after
seed_provider: [{seeds: "10.0.0.1:7000,10.0.0.2:7000"}] // seeds of your cluster
Defensive patterns

Strategy: try-catch

Validate before calling

if (remote.getIdentifier() != ClusterMetadata.current().metadataIdentifier
    && remote.getIdentifier() != ClusterMetadata.EMPTY_METADATA_IDENTIFIER)
    throw new CMSIdentifierMismatchException("Peer from a different cluster: " + remote.getIdentifier());

Try / catch

try {
    messaging.exchangeMetadata(...);
} catch (CMSIdentifierMismatchException e) {
    logger.error("Cluster identity mismatch, halting communication: {}", e.getMessage());
    // stop messaging, alert operator
}

Prevention

When it happens

Trigger: Receiving a message/metadata snapshot whose remote cluster identifier differs from the local one, where the remote identifier is not the empty sentinel. Typically during peer exchange after a bad join, restored-from-backup state, or split/parallel cluster formation.

Common situations: A node cloned from a different cluster, stale seeds pointing at another cluster, restored metadata log from a different cluster, or a node re-initialized with a new identifier while old peers still run the old one.

Related errors


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