apache/pulsar · error · IllegalArgumentException
Range end must >= range start.
Error message
Range end must >= range start.
What it means
The Range constructor validates that end >= start and throws IllegalArgumentException otherwise. A Range with an inverted interval is meaningless in Pulsar's hash-space model (used for KeyShared sticky ranges), so the constructor refuses to create such an object rather than propagating a broken invariant to downstream intersection/containment logic.
Source
Thrown at pulsar-client-api/src/main/java/org/apache/pulsar/client/api/Range.java:40
import java.util.Objects;
import org.apache.pulsar.common.classification.InterfaceAudience;
import org.apache.pulsar.common.classification.InterfaceStability;
/**
* Int range.
*/
@InterfaceAudience.Public
@InterfaceStability.Stable
public class Range implements Comparable<Range>, Serializable {
private static final long serialVersionUID = 1L;
private final int start;
private final int end;
public Range(int start, int end) {
if (end < start) {
throw new IllegalArgumentException("Range end must >= range start.");
}
this.start = start;
this.end = end;
}
public static Range of(int start, int end) {
return new Range(start, end);
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public Range intersect(Range range) {View on GitHub (pinned to 820761864e)
Solutions
- Swap the arguments so the smaller value is the start: Range.of(Math.min(a, b), Math.max(a, b)).
- Normalize inputs before constructing: reject or clamp inverted intervals in your own config-loading code.
- If a range legitimately became empty, model it explicitly (skip it) rather than constructing an inverted Range.
Example fix
// before Range range = Range.of(end, start); // after Range range = Range.of(Math.min(start, end), Math.max(start, end));
Defensive patterns
Strategy: validation
Validate before calling
static Range safeRange(int a, int b) {
if (b < a) throw new IllegalArgumentException("end < start: " + a + ", " + b);
return Range.of(a, b);
} Type guard
static boolean isValidInterval(int start, int end) {
return end >= start;
} Try / catch
try {
Range r = Range.of(start, end);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Range end must >= range start")) {
Range r = Range.of(Math.min(start, end), Math.max(start, end)); // normalize
} else throw e;
} Prevention
- Normalize with Math.min/Math.max at every construction site fed by variables.
- Validate config-loaded boundaries before they reach Range.of.
- Keep start/end as adjacent parameters in named factory methods to avoid argument swaps.
When it happens
Trigger: Calling new Range(100, 50) or Range.of(100, 50) directly — any construction where the end is strictly less than the start.
Common situations: Swapped arguments when computing range boundaries from variables (Range.of(end, start)); computing start/end from user input or config where the ordering was never normalized; splitting logic that emits (high, low) by mistake.
Related errors
- Invalid range ${range}
- Split service unit should be split into 2 service units.
- ResourceGroupCreate: Invalid null ResourceGroup config
- ResourceGroupCreate: can't create resource group with an emp
- ${name} is NULL, empty or contains a '&'
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/0eb63a7c822bd130.
Report an issue: GitHub.