apache/pulsar · error · IllegalArgumentException
Ranges must be [0, 65535] but provided range is
Error message
Ranges must be [0, 65535] but provided range is
What it means
ReaderBuilder.keyHashRange() restricts each key-hash Range to fit within the non-negative space of the default hash range (0..65535, DEFAULT_HASH_RANGE_SIZE). Passing a range that starts below 0 or ends above 65535 throws this IllegalArgumentException because keys would never hash into such a range.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/ReaderBuilderImpl.java:241
public ReaderBuilder<T> subscriptionName(String subscriptionName) {
conf.setSubscriptionName(subscriptionName);
return this;
}
@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;
}View on GitHub (pinned to 820761864e)
Solutions
- Clamp all ranges so start >= 0 and end <= 65535
- Compute ranges as fractions of DEFAULT_HASH_RANGE_SIZE (65536 slots, inclusive end 65535) rather than the raw hash width
- Check each Range endpoint before calling keyHashRange
Example fix
// before readerBuilder.keyHashRange(Range.of(0, 100000)); // after readerBuilder.keyHashRange(Range.of(0, 65535));
Defensive patterns
Strategy: validation
Validate before calling
for (Range r : ranges) {
if (r.getStart() < 0 || r.getEnd() > 65535) {
throw new IllegalArgumentException("Range out of [0,65535]: " + r);
}
} Type guard
boolean isValidHashRange(Range r) {
return r != null && r.getStart() >= 0 && r.getEnd() <= 65535;
} Try / catch
try {
readerBuilder.keyHashRange(ranges);
} catch (IllegalArgumentException e) {
log.error("Invalid key hash range: {}", e.getMessage());
throw new ConfigurationException("keyHashRange endpoints must be within [0, 65535]", e);
} Prevention
- Derive ranges from the 65536-slot default hash size, never from raw hash bit width
- Clamp and validate endpoints before building the ranges
- Add a startup-time config validation for all key hash ranges
When it happens
Trigger: Calling keyHashRange(Range.of(start, end)) where start < 0 or end > 65535, e.g. Range.of(0, 131071) or Range.of(-10, 100). Note the thrown message omits the interpolated range value.
Common situations: Computing ranges from a different hash-size assumption (e.g. full 32-bit hash space instead of the 65536-slot range), splitting a larger interval evenly and rounding past 65535, or typos when defining ranges for a non-overlapping reader subscription.
Related errors
- Key hash ranges with overlap between and
- 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/16184e232e031c55.
Report an issue: GitHub.