apache/cassandra · error · IllegalArgumentException
Start and end tokens must be different.
Error message
Start and end tokens must be different.
What it means
RepairOption.parseRanges parses user-supplied token ranges of the form begin:end and throws IllegalArgumentException if begin and end tokens are equal, because Range(token,token) is an empty range and not a valid repair range (ranges are [start, end)).
Source
Thrown at src/java/org/apache/cassandra/repair/messages/RepairOption.java:92
public static Set<Range<Token>> parseRanges(String rangesStr, IPartitioner partitioner)
{
if (rangesStr == null || rangesStr.isEmpty())
return Collections.emptySet();
Set<Range<Token>> ranges = new HashSet<>();
StringTokenizer tokenizer = new StringTokenizer(rangesStr, ",");
while (tokenizer.hasMoreTokens())
{
String[] rangeStr = tokenizer.nextToken().split(":", 2);
if (rangeStr.length < 2)
{
continue;
}
Token parsedBeginToken = partitioner.getTokenFactory().fromString(rangeStr[0].trim());
Token parsedEndToken = partitioner.getTokenFactory().fromString(rangeStr[1].trim());
if (parsedBeginToken.equals(parsedEndToken))
{
throw new IllegalArgumentException("Start and end tokens must be different.");
}
ranges.add(new Range<>(parsedBeginToken, parsedEndToken));
}
return ranges;
}
/**
* Construct RepairOptions object from given map of Strings.
* <p>
* Available options are:
*
* <table>
* <caption>Repair Options</caption>
* <thead>
* <tr>
* <th>key</th>
* <th>value</th>
* <th>default (when key not given)</th>View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove the degenerate range and provide distinct start/end tokens
- To repair the full ring, omit range options entirely (defaults to local node's ranges)
- Use proper wrap-around notation (minToken, token] for wrap-around coverage instead of x:x
Example fix
// before nodetool repair ks --ranges 1:1 // after nodetool repair -pr ks # or use distinct tokens like 1:100
Defensive patterns
Strategy: validation
Validate before calling
for (String r : rangeSpecs) {
String[] parts = r.split(":");
if (parts.length == 2 && parts[0].trim().equals(parts[1].trim()))
throw new IllegalArgumentException("Degenerate range " + r + ": start and end tokens must differ");
} Try / catch
try { RepairOption.parse(opts, partitioner); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("Start and end tokens must be different"))
logger.warn("Fix range arguments; drop degenerate ranges", e);
else throw e;
} Prevention
- Never emit x:x ranges in automation; drop them instead
- Omit range options to repair full/local ranges
- Deduplicate and sanity-check token range strings before repair
When it happens
Trigger: Calling nodetool repair with --ranges (or RepairOption.ranges()) where a range string has identical start and end tokens, e.g. `1:1`.
Common situations: Hand-written range lists in scripts; misunderstanding that (x,x) means the full ring instead of an empty range; automation generating degenerate range strings.
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
- Cannot set repair_session_max_tree_depth to which is < 10, d
- Value must be >= 0 and <= 1 for repair_disk_headroom_reject_
- Cannot specify a repair as both paxos only and accord only
- Cannot run paxos only repair on %s.%s, which isn't configure
- Cannot run accord only repair on %s.%s, which isn't configur
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/e99994dfb35d7b20.
Report an issue: GitHub.