apache/cassandra · error · IllegalArgumentException

You need to run primary range repair on all nodes in the clu

Error message

You need to run primary range repair on all nodes in the cluster.

What it means

When a repair is requested with -pr (primary ranges) and the option neither specifies datacenters nor hosts, the node must compute the primary ranges for the whole cluster; if the request is restricted to the local DC only (inLocalDCOnly) the full-cluster primary range set cannot be derived, so IllegalArgumentException is thrown. Effectively, -local and -pr are incompatible in this path.

Source

Thrown at src/java/org/apache/cassandra/service/StorageService.java:3161

        RepairOption option = RepairOption.parse(repairSpec, partitioner);
        return repair(keyspace, option, listeners);
    }

    public Pair<Integer, Future<?>> repair(String keyspace, RepairOption option, List<ProgressListener> listeners)
    {
        // if ranges are not specified
        if (option.getRanges().isEmpty())
        {
            if (option.isPrimaryRange())
            {
                // when repairing only primary range, neither dataCenters nor hosts can be set
                if (option.getDataCenters().isEmpty() && option.getHosts().isEmpty())
                    option.getRanges().addAll(getPrimaryRanges(keyspace));
                    // except dataCenters only contain local DC (i.e. -local)
                else if (option.isInLocalDCOnly())
                    option.getRanges().addAll(getPrimaryRangesWithinDC(keyspace));
                else
                    throw new IllegalArgumentException("You need to run primary range repair on all nodes in the cluster.");
            }
            else
            {
                Iterables.addAll(option.getRanges(), getLocalReplicas(keyspace).onlyFull().ranges());
            }
        }
        if (option.getRanges().isEmpty() || Keyspace.open(keyspace).getReplicationStrategy().getReplicationFactor().allReplicas < 2)
            return Pair.create(0, ImmediateFuture.success(null));

        int cmd = nextRepairCommand.incrementAndGet();
        return Pair.create(cmd, repairCommandExecutor().submit(createRepairTask(cmd, keyspace, option, listeners)));
    }

    /**
     * Create collection of ranges that match ring layout from given tokens.
     *
     * @param beginToken beginning token of the range
     * @param endToken end token of the range

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove -local when using -pr (run primary-range repair cluster-wide, on all nodes)
  2. Or drop -pr and keep -local to repair all ranges in the local DC
  3. Or use -pr with explicit -dc list including the local DC

Example fix

// before
nodetool repair -pr -local my_keyspace
// after
nodetool repair -pr my_keyspace   # run on every node, no -local
Defensive patterns

Strategy: validation

Validate before calling

RepairOption opt = RepairOption.parse(...);
if (opt.isPrimaryRange() && opt.isInLocalDCOnly())
    throw new IllegalArgumentException("-pr and -local cannot be combined");

Try / catch

try { ss.repairAsync(ks, opt); } catch (IllegalArgumentException e) { /* adjust repair flags */ }

Prevention

When it happens

Trigger: Invoking `nodetool repair -pr -local <keyspace>` or calling StorageService.repairAsync with RepairOption where isPrimaryRange()=true, isInLocalDCOnly()=true, and datacenters/hosts are empty.

Common situations: Operator combining -pr with -local in nodetool scripts assuming they compose; migrating old repair scripts to newer Cassandra versions where option validation tightened.

Related errors


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