apache/cassandra · error · ConfigurationException

Token allocation failed: the number of racks

Error message

Token allocation failed: the number of racks %d in datacenter %s is lower than its replication factor %d.

What it means

In TokenAllocation.createStrategy, when a datacenter has more than one rack but fewer racks than the replication factor, the allocator cannot satisfy rack-aware replica placement, so it throws ConfigurationException. The replication factor must be <= the number of racks (or the DC must have exactly 1 rack with appropriate handling).

Solutions

  1. Increase replication factor to <= number of racks, or add more racks and distribute nodes
  2. If single-rack semantics are acceptable, consolidate to one rack or accept rack-grouping behavior and set the replication factor to the actual rack count
  3. Check nodetool status output to verify node DC/rack assignments match expectations
  4. Fix rack configuration in cassandra-rackdc.properties and restart nodes before allocation

Example fix

// before
ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3}; // dc1 has only 2 racks
// after
ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':2}; // matches rack count
Defensive patterns

Strategy: validation

Validate before calling

// replication factor must be <= number of racks in each DC
Map<String,Integer> racksPerDc = collectRacksPerDc(); // from snitch metadata
racksPerDc.forEach((dc, racks) -> {
    int rf = strategy.getReplicationFactor(dc);
    if (rf > racks) throw new IllegalArgumentException(
        String.format("RF %d > racks %d in %s", rf, racks, dc));
});

Try / catch

try {
    TokenAllocation.allocate(metadata, ks, dc);
} catch (ConfigurationException e) {
    if (e.getMessage().contains("number of racks")) {
        // lower RF or add racks, then retry
    }
}

Prevention

When it happens

Trigger: Calling allocate for a keyspace using NetworkTopologyStrategy whose replication factor for a DC exceeds that DC's rack count (with racks > 1).

Common situations: NetworkTopologyStrategy configured with replication_factor 3 in a DC with only 2 racks; misconfigured cassandra-rackdc.properties so nodes report wrong racks; adding racks after strategy change.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/dht/tokenallocator/TokenAllocation.java:299

            // each node is treated as separate and replicates once
            return createStrategy(locator, dc, null, 1, false);
        }
        else if (racks == replicas)
        {
            // each node is treated as separate and replicates once, with separate allocation rings for each rack
            return createStrategy(locator, dc, rack, 1, false);
        }
        else if (racks > replicas)
        {
            // group by rack
            return createStrategy(locator, dc, null, replicas, true);
        }
        else if (racks == 1)
        {
            return createStrategy(locator, dc, null, replicas, false);
        }

        throw new ConfigurationException(String.format("Token allocation failed: the number of racks %d in datacenter %s is lower than its replication factor %d.",
                                                       racks, dc, replicas));
    }

    // a null dc will always return true for inAllocationRing(..)
    // a null rack will return true for inAllocationRing(..) for all nodes in the same dc
    private StrategyAdapter createStrategy(Supplier<Locator> locator, String dc, String rack, int replicas, boolean groupByRack)
    {
        return new StrategyAdapter()
        {
            @Override
            public int replicas()
            {
                return replicas;
            }

            @Override
            public Object getGroup(InetAddressAndPort unit)
            {

View on GitHub (pinned to 88fd0f6a0e)