apache/pulsar · error · IllegalArgumentException
Key hash ranges with overlap between and
Error message
Key hash ranges with overlap between and
What it means
ReaderBuilder.keyHashRange() requires the supplied ranges to be mutually disjoint; overlapping ranges make key assignment for a non-overlapping reader ambiguous. When Range.intersect(range2) returns non-null for two distinct ranges, this IllegalArgumentException is thrown.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/ReaderBuilderImpl.java:246
@Override
public ReaderBuilder<T> readCompacted(boolean readCompacted) {
conf.setReadCompacted(readCompacted);
return this;
}
@Override
public ReaderBuilder<T> keyHashRange(Range... ranges) {
checkArgument(ranges != null && ranges.length > 0,
"Cannot specify a null ofr an empty key hash ranges for a reader");
for (int i = 0; i < ranges.length; i++) {
Range range1 = ranges[i];
if (range1.getStart() < 0 || range1.getEnd() > DEFAULT_HASH_RANGE_SIZE) {
throw new IllegalArgumentException("Ranges must be [0, 65535] but provided range is " + range1);
}
for (int j = 0; j < ranges.length; j++) {
Range range2 = ranges[j];
if (i != j && range1.intersect(range2) != null) {
throw new IllegalArgumentException("Key hash ranges with overlap between " + range1
+ " and " + range2);
}
}
}
conf.setKeyHashRanges(Arrays.asList(ranges));
return this;
}
@Override
public ReaderBuilder<T> poolMessages(boolean poolMessages) {
conf.setPoolMessages(poolMessages);
return this;
}
@Override
public ReaderBuilder<T> autoUpdatePartitions(boolean autoUpdate) {
this.conf.setAutoUpdatePartitions(autoUpdate);
return this;View on GitHub (pinned to 820761864e)
Solutions
- Make ranges strictly non-overlapping, e.g. [0, 32766] and [32767, 65535] with inclusive endpoints
- De-duplicate the ranges array before passing it
- Validate pairwise intersections in your own code before calling keyHashRange
Example fix
// before readerBuilder.keyHashRange(Range.of(0, 32767), Range.of(32767, 65535)); // 32767 overlaps // after readerBuilder.keyHashRange(Range.of(0, 32766), Range.of(32767, 65535));
Defensive patterns
Strategy: validation
Validate before calling
for (int i = 0; i < ranges.length; i++) {
for (int j = i + 1; j < ranges.length; j++) {
if (ranges[i].intersect(ranges[j]) != null) {
throw new IllegalArgumentException("Overlapping ranges: " + ranges[i] + " and " + ranges[j]);
}
}
} Type guard
boolean areDisjoint(Range... ranges) {
for (int i = 0; i < ranges.length; i++)
for (int j = i + 1; j < ranges.length; j++)
if (ranges[i].intersect(ranges[j]) != null) return false;
return true;
} Try / catch
try {
readerBuilder.keyHashRange(ranges);
} catch (IllegalArgumentException e) {
log.error("Overlapping key hash ranges: {}", e.getMessage());
throw new ConfigurationException("Key hash ranges must be disjoint", e);
} Prevention
- Remember range endpoints are inclusive; partition with end = nextStart - 1
- De-duplicate ranges before passing them
- Programmatically generate disjoint partitions instead of hand-writing boundaries
When it happens
Trigger: Calling keyHashRange with two or more ranges that share any portion of the [0,65535] space, e.g. Range.of(0, 32767) and Range.of(32767, 65535) (both contain 32767), or duplicated ranges like (0,10) specified twice.
Common situations: Splitting the hash space at shared boundaries while forgetting range endpoints are inclusive, generating ranges programmatically with a step that overlaps at boundaries, or passing the same range twice in the varargs list.
Related errors
- Ranges must be [0, 65535] but provided range is
- The shared resource doesn't support thread pool configurati
- No resources have been configured while using shareConfigure
- Invalid value %s for the position. Allowed values are [lates
- Error creating client for HealthChecker
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/20e1104ad7ff3675.
Report an issue: GitHub.