apache/cassandra · critical · IllegalStateException

When reinitializing with cluster metadata, the same partitio

Error message

When reinitializing with cluster metadata, the same partitioner must be used. Configured: %s, Serialized: %s

What it means

Startup.reinitializeWithClusterMetadata loads a previously serialized ClusterMetadata snapshot (from a file, typically after restoring node state) and validates it against the current configuration. Since the partitioner determines token and data layout, a serialized metadata whose partitioner differs from DatabaseDescriptor.getPartitioner() cannot be applied; the node throws IllegalStateException naming both partitioner class names. Using mismatched metadata would corrupt token/ring assignments.

Source

Thrown at src/java/org/apache/cassandra/tcm/Startup.java:595

        {
            cmGossip.dumpDiff(initial);
            throw new AssertionError("Issue when populating gossip from cluster metadata");
        }
    }

    public static void reinitializeWithClusterMetadata(String fileName, Function<Processor, Processor> wrapProcessor, Runnable initMessaging) throws IOException, StartupException
    {
        ClusterMetadata prev = ClusterMetadata.currentNullable();
        // First set a minimal ClusterMetadata as some deserialization depends
        // on ClusterMetadata.current() to access the partitioner
        StubClusterMetadataService initial = StubClusterMetadataService.forClientTools();
        ClusterMetadataService.unsetInstance();
        StubClusterMetadataService.setInstance(initial);

        ClusterMetadata metadata = ClusterMetadataService.deserializeClusterMetadata(fileName);
        // if the partitioners are mismatching, we probably won't even get this far
        if (metadata.partitioner != DatabaseDescriptor.getPartitioner())
            throw new IllegalStateException(String.format("When reinitializing with cluster metadata, the same " +
                                                          "partitioner must be used. Configured: %s, Serialized: %s",
                                                          DatabaseDescriptor.getPartitioner().getClass().getCanonicalName(),
                                                          metadata.partitioner.getClass().getCanonicalName()));

        if (!metadata.isCMSMember())
            throw new IllegalStateException("When reinitializing with cluster metadata, we must be in the CMS");

        metadata = metadata.forceEpoch(metadata.epoch.nextEpoch());
        ClusterMetadataService.unsetInstance();
        LocalLog.LogSpec logSpec = LocalLog.logSpec()
                                           .afterReplay(Startup::scrubDataDirectories,
                                                        (_metadata) -> StorageService.instance.registerMBeans())
                                           .withPreviousState(prev)
                                           .withInitialState(metadata)
                                           .withStorage(LogStorage.SystemKeyspace)
                                           .withDefaultListeners()
                                           .isReset(true);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Set the partitioner in cassandra.yaml to match the serialized metadata's partitioner (the class name is printed in the error).
  2. Alternatively re-generate/export the cluster metadata snapshot from a cluster running the desired partitioner.
  3. Never switch partitioners on an existing cluster's data — pick one partitioner and keep the snapshot and config aligned.
  4. Verify with the class names in the message (configured vs serialized) which side to change.

Example fix

# before: config mismatches snapshot
partitioner: org.apache.cassandra.dht.RandomPartitioner   # snapshot is Murmur3Partitioner
# after:
partitioner: org.apache.cassandra.dht.Murmur3Partitioner
Defensive patterns

Strategy: validation

Validate before calling

// before reinitializing, compare partitioners
if (!metadata.partitioner.getClass().equals(DatabaseDescriptor.getPartitioner().getClass()))
    throw new ConfigurationException("Partitioner mismatch between snapshot and config");

Try / catch

try { Startup.reinitializeWithClusterMetadata(fileName); }
catch (IllegalStateException e) {
    if (e.getMessage().contains("same partitioner must be used")) {
        // align cassandra.yaml partitioner with the snapshot, restart
    } else throw e;
}

Prevention

When it happens

Trigger: reinitializeWithClusterMetadata deserializes metadata via ClusterMetadataService.deserializeClusterMetadata(fileName) and metadata.partitioner != DatabaseDescriptor.getPartitioner(); the snapshot was taken with a different partitioner (e.g. Murmur3Partitioner vs RandomPartitioner) than the current cassandra.yaml partitioner setting.

Common situations: Restoring a node/cluster backup into a cluster reconfigured to a different partitioner; copying a metadata dump between clusters (test vs prod) with different partitioner settings; hand-edited cassandra.yaml changing partitioner before reinitialization.

Related errors


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