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

  1. Clamp all ranges so start >= 0 and end <= 65535
  2. Compute ranges as fractions of DEFAULT_HASH_RANGE_SIZE (65536 slots, inclusive end 65535) rather than the raw hash width
  3. 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

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


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/16184e232e031c55. Report an issue: GitHub.