apache/cassandra · error · IllegalArgumentException

Simple placement can only specify a single replication facto

Error message

Simple placement can only specify a single replication factor across all data centers

What it means

With simple placement, nodetool cms accepts only ONE replication factor applying to all datacenters. execute() throws IllegalArgumentException when multiple positional args are given but none contains ':' — i.e. multiple plain integers were passed for a per-cluster RF.

Source

Thrown at src/java/org/apache/cassandra/tools/nodetool/CMSAdmin.java:171

                return;
            }

            if (cancel)
            {
                probe.getCMSOperationsProxy().cancelReconfigureCms();
                return;
            }

            if (args.isEmpty())
                throw new IllegalArgumentException("Replication factor is empty");

            Map<String, Integer> parsedRfs = new HashMap<>(args.size());
            for (String rf : args)
            {
                if (!rf.contains(":"))
                {
                    if (args.size() > 1)
                        throw new IllegalArgumentException("Simple placement can only specify a single replication factor across all data centers");
                    int parsedRf;
                    try
                    {
                        parsedRf = Integer.parseInt(args.get(0));
                    }
                    catch (Throwable t)
                    {
                        throw new IllegalArgumentException(String.format("Can not parse replication factor from %s", args.get(0)));
                    }
                    probe.getCMSOperationsProxy().reconfigureCMS(parsedRf);
                    return;
                }
                else
                {
                    String[] splits = rf.split(":");
                    if (splits.length > 2)
                        throw new IllegalArgumentException(String.format("Can not parse replication factor %s", rf));
                    String dc = splits[0];

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. For a single cluster-wide RF pass one number: nodetool cms 3
  2. For per-DC RFs use dc-prefixed args: nodetool cms dc1:3,dc2:5
  3. Quote as a single arg if needed: nodetool cms "dc1:3,dc2:5"

Example fix

// before
nodetool cms 3 5
// after
nodetool cms dc1:3,dc2:5
Defensive patterns

Strategy: validation

Validate before calling

if (rfArgs.stream().noneMatch(a -> a.contains(":")) && rfArgs.size() > 1)
    throw new IllegalArgumentException("Use one plain RF for all DCs, or dc:rf pairs");

Prevention

When it happens

Trigger: Running 'nodetool cms 3 5' or 'nodetool cms 3,5' (split into multiple args) intending per-DC factors but omitting the dc name prefixes.

Common situations: Trying to set different RF per DC without the dc: syntax; passing a comma-separated list that the shell splits into two args; misunderstanding simple vs. denormalized placement syntax.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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