apache/cassandra · error · IllegalArgumentException

Specified hosts do not share range needed for repair…

Error message

Specified hosts %s do not share range %s needed for repair. Either restrict repair ranges with -st/-et options, or specify one of the neighbors that share this range with this node: %s.

What it means

After filtering the -hosts list to nodes that share the repair range, if only the local node (or fewer than 2 hosts) remains, no neighbor exists to repair against. Cassandra throws this IllegalArgumentException explaining that the specified hosts do not share the range and suggesting restricting ranges or picking real neighbors.

Solutions

  1. Run nodetool describering/ring to find which nodes share the target range and list those in -hosts
  2. Restrict the repair with -st/-et so the range matches the ranges the specified hosts share
  3. Drop the -hosts option entirely to let Cassandra pick the correct neighbors

Example fix

// before
nodetool repair keyspace1 -st A -et B -hosts node1,node7  # node7 not a replica of [A,B]
// after
nodetool repair keyspace1 -st A -et B -hosts node1,node2  # node2 replica of [A,B]
Defensive patterns

Strategy: validation

Validate before calling

// confirm at least one specified host is a peer replica for the range
Collection<InetAddressAndPort> natural = storageService.getNaturalEndpoints(keyspace, rangeToken);
boolean hasNeighbor = hosts.stream().anyMatch(h -> !h.equals(local) && natural.contains(h));

Try / catch

try { repair(...); }
catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Specified hosts")) log.error("hosts don't share range; use describering", e);
    throw e;
}

Prevention

When it happens

Trigger: Specifying -hosts where none of the other hosts is a replica (neighbor) for the token range being repaired, e.g. listing nodes from a different datacenter/rack that don't hold the range, or listing only the local node plus non-replica nodes.

Common situations: Operators picking hosts manually for a sub-range repair without checking ring ownership (nodetool ring/describering); topology changes moved range ownership since the host list was written.

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/e0fb2f47445b5910. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/service/ActiveRepairService.java:656

                    final InetAddressAndPort endpoint = InetAddressAndPort.getByName(host.trim());
                    if (endpoint.equals(ctx.broadcastAddressAndPort()) || neighbors.endpoints().contains(endpoint))
                        specifiedHost.add(endpoint);
                }
                catch (UnknownHostException e)
                {
                    throw new IllegalArgumentException("Unknown host specified " + host, e);
                }
            }

            if (!specifiedHost.contains(ctx.broadcastAddressAndPort()))
                throw new IllegalArgumentException("The current host must be part of the repair");

            if (specifiedHost.size() <= 1)
            {
                String msg = "Specified hosts %s do not share range %s needed for repair. Either restrict repair ranges " +
                             "with -st/-et options, or specify one of the neighbors that share this range with " +
                             "this node: %s.";
                throw new IllegalArgumentException(String.format(msg, hosts, toRepair, neighbors));
            }

            specifiedHost.remove(ctx.broadcastAddressAndPort());
            return neighbors.keep(specifiedHost);
        }

        return neighbors;
    }

    /**
     * we only want to set repairedAt for incremental repairs including all replicas for a token range. For non-global
     * incremental repairs, forced incremental repairs, and full repairs, the UNREPAIRED_SSTABLE value will prevent
     * sstables from being promoted to repaired or preserve the repairedAt/pendingRepair values, respectively.
     */
    long getRepairedAt(RepairOption options, boolean force)
    {
        // we only want to set repairedAt for incremental repairs including all replicas for a token range. For non-global incremental repairs, full repairs, the UNREPAIRED_SSTABLE value will prevent
        // sstables from being promoted to repaired or preserve the repairedAt/pendingRepair values, respectively. For forced repairs, repairedAt time is only set to UNREPAIRED_SSTABLE if we actually

View on GitHub (pinned to 88fd0f6a0e)