apache/cassandra · error · ConfigurationException

replication_factor should not appear as an option to…

Error message

replication_factor should not appear as an option to NetworkTopologyStrategy

What it means

NetworkTopologyStrategy assigns replication per datacenter (e.g. 'dc1': 3) and does not accept a flat 'replication_factor' option. prepareOptions normally converts legacy SimpleStrategy-style options, but if a literal 'replication_factor' key remains in the options when validateOptions runs, this ConfigurationException is thrown to reject the invalid configuration.

Solutions

  1. Remove 'replication_factor' from the options and specify per-DC factors instead: {'class':'NetworkTopologyStrategy','dc1':3,'dc2':2}
  2. Run ALTER KEYSPACE with the corrected replication map and repair as needed
  3. Check for tooling/ORM layers that inject replication_factor and fix their strategy templates

Example fix

// before
CREATE KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','replication_factor':3};
// after
CREATE KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3,'dc2':3};
Defensive patterns

Strategy: validation

Validate before calling

if (replicationOpts.containsKey("replication_factor") && "NetworkTopologyStrategy".equals(replicationOpts.get("class")))
    throw new IllegalArgumentException("replication_factor is invalid for NetworkTopologyStrategy; use per-DC values");

Try / catch

try { session.execute(alterKeyspaceCql); } catch (InvalidQueryException e) { if (e.getMessage().contains("replication_factor")) { /* strip the option and retry */ } }

Prevention

When it happens

Trigger: CREATE/ALTER KEYSPACE with {'class':'NetworkTopologyStrategy','replication_factor':'3'} — i.e. passing a replication_factor option that was not normalized by prepareOptions.

Common situations: Copy-pasting a SimpleStrategy replication definition when switching strategies; migration scripts converting keyspaces from SimpleStrategy; hand-edited schema files.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java:380

        if (keyspaceName.equalsIgnoreCase(SchemaConstants.AUTH_KEYSPACE_NAME))
        {
            Set<String> differenceSet = Sets.difference(metadata.directory.knownDatacenters(), configOptions.keySet());
            if (!differenceSet.isEmpty())
            {
                throw new ConfigurationException("Following datacenters have active nodes and must be present in replication options for keyspace " + SchemaConstants.AUTH_KEYSPACE_NAME + ": " + differenceSet.toString());
            }
        }
        logger.info("Configured datacenter replicas are {}", FBUtilities.toString(datacenters));
    }

    @Override
    public void validateOptions() throws ConfigurationException
    {
        for (Entry<String, String> e : this.configOptions.entrySet())
        {
            // prepareOptions should have transformed any "replication_factor" by now
            if (e.getKey().equalsIgnoreCase(REPLICATION_FACTOR))
                throw new ConfigurationException(REPLICATION_FACTOR + " should not appear as an option to NetworkTopologyStrategy");
            validateReplicationFactor(e.getValue());
        }
    }

    @Override
    public void maybeWarnOnOptions(ClientState state)
    {
        if (!SchemaConstants.isSystemKeyspace(keyspaceName))
        {
            Directory directory = ClusterMetadata.current().directory;
            Multimap<String, InetAddressAndPort> dcsNodes = directory.allDatacenterEndpoints();
            for (Entry<String, String> e : this.configOptions.entrySet())
            {
                String dc = e.getKey();
                ReplicationFactor rf = getReplicationFactor(dc);
                Guardrails.minimumReplicationFactor.guard(rf.fullReplicas, keyspaceName, false, state);
                Guardrails.maximumReplicationFactor.guard(rf.fullReplicas, keyspaceName, false, state);
                int nodeCount = dcsNodes.containsKey(dc) ? dcsNodes.get(dc).size() : 0;

View on GitHub (pinned to 88fd0f6a0e)