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

KeySharedPolicy.KeySharedPolicySticky.validate() rejects a sticky hash range whose start is negative or whose end is >= DEFAULT_HASH_RANGE_SIZE (65535). Pulsar's KeyShared sticky dispatcher maps message keys onto a fixed 0..65535 hash space, so any range outside those bounds can never match a key and would silently steal/lose assignments. The library fails fast with IllegalArgumentException at attach time rather than mis-routing at runtime.

Source

Thrown at pulsar-client-api/src/main/java/org/apache/pulsar/client/api/KeySharedPolicy.java:114

        public KeySharedPolicySticky ranges(List<Range> ranges) {
            this.ranges.addAll(ranges);
            return this;
        }

        public KeySharedPolicySticky ranges(Range... ranges) {
            this.ranges.addAll(Arrays.asList(ranges));
            return this;
        }

        @Override
        public void validate() {
            if (ranges.isEmpty()) {
                throw new IllegalArgumentException("Ranges for KeyShared policy must not be empty.");
            }
            for (int i = 0; i < ranges.size(); i++) {
                Range range1 = ranges.get(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.size(); j++) {
                    Range range2 = ranges.get(j);
                    if (i != j && range1.intersect(range2) != null) {
                        throw new IllegalArgumentException("Ranges for KeyShared policy with overlap between " + range1
                                + " and " + range2);
                    }
                }
            }
        }

        public List<Range> getRanges() {
            return ranges;
        }
    }

    /**
     * Auto split hash range key shared policy.

View on GitHub (pinned to 820761864e)

Solutions

  1. Clamp every range so start >= 0 and end <= 65534 (the valid hash space is [0, 65535) exclusive at the top).
  2. Replace Range.of(0, 65535) with Range.of(0, 65534) for a full-space single range.
  3. Validate ranges client-side with Range.of and a bounds check before building the policy, so the consumer fails at construction, not at subscribe.

Example fix

// before
KeySharedPolicy policy = KeySharedPolicy.stickyRanges(
    Collections.singletonList(Range.of(0, 65535)));
// after
KeySharedPolicy policy = KeySharedPolicy.stickyRanges(
    Collections.singletonList(Range.of(0, 65534))); // max end is 65534
Defensive patterns

Strategy: validation

Validate before calling

static void checkRange(Range r) {
    if (r.getStart() < 0 || r.getEnd() >= 65535)
        throw new IllegalArgumentException("Range out of [0, 65535): " + r);
}
ranges.forEach(MyClass::checkRange); // before KeySharedPolicy.stickyRanges(...)

Type guard

static boolean isValidHashRange(Range r) {
    return r != null && r.getStart() >= 0 && r.getEnd() < 65535;
}

Try / catch

try {
    consumer = client.newConsumer().keySharedPolicy(KeySharedPolicy.stickyRanges(ranges)).subscribe();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Ranges must be [0, 65535]")) {
        // fix or clamp the offending range reported in e.getMessage()
    } else throw e;
}

Prevention

When it happens

Trigger: Calling KeySharedPolicy.stickyRanges(...) (then attaching a consumer) with a Range built as Range.of(-1, 100) or Range.of(0, 65535) — any range whose start < 0 or end >= 65535 passes into validate().

Common situations: Off-by-one: developers assume the range is inclusive of 65535 like a 16-bit unsigned value, writing Range.of(0, 65535); treating the range as 1-based (starting at 1 is fine but ending at 65535 is not); hand-computed partitions after resizing that drift below zero.

Related errors


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