apache/pulsar · error · IllegalArgumentException

Ranges for KeyShared policy must not be empty.

Error message

Ranges for KeyShared policy must not be empty.

What it means

KeySharedPolicy.KeySharedPolicySticky.validate() rejects a sticky ranges policy whose list of hash ranges is empty, throwing IllegalArgumentException. A sticky KeyShared consumer must partition the 0-65535 hash space into at least one non-empty range; an empty list would leave the consumer unable to receive any messages.

Source

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

        KeySharedPolicySticky() {
            this.keySharedMode = KeySharedMode.STICKY;
            this.ranges = new ArrayList<>();
        }

        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;

View on GitHub (pinned to 820761864e)

Solutions

  1. Provide at least one Range, e.g. Range.of(0, 65535) to cover the full hash space.
  2. Fix range-splitting code so it always yields non-empty ranges for all consumers.
  3. Catch IllegalArgumentException and fall back to KeySharedPolicy.autoSplitHashRange() when no ranges are configured.
  4. Ensure each range is within [0, 65535] to avoid the related out-of-range error.

Example fix

// before
KeySharedPolicy policy = KeySharedPolicy.stickyRanges()
    .ranges(Collections.emptyList());
// after
KeySharedPolicy policy = KeySharedPolicy.stickyRanges()
    .ranges(Collections.singletonList(Range.of(0, 65535)));
Defensive patterns

Strategy: validation

Validate before calling

List<Range> ranges = /* computed ranges */;
if (ranges == null || ranges.isEmpty()) {
    ranges = Collections.singletonList(Range.of(0, 65535));
}
ranges.forEach(r -> {
    if (r.getStart() < 0 || r.getEnd() >= 65536) {
        throw new IllegalArgumentException("Range out of [0,65535]: " + r);
    }
});
KeySharedPolicy policy = KeySharedPolicy.stickyRanges().ranges(ranges);

Try / catch

try {
    consumerBuilder.keySharedPolicy(stickyPolicy);
} catch (IllegalArgumentException e) {
    log.warn("Invalid sticky ranges, falling back to auto split: {}", e.getMessage());
    consumerBuilder.keySharedPolicy(KeySharedPolicy.autoSplitHashRange());
}

Prevention

When it happens

Trigger: ConsumerBuilder.keySharedPolicy(KeySharedPolicy.stickyRanges().ranges(new ArrayList<>())) or an empty Range list passed to ranges(...), then subscribe()/validate runs. Also fired when the list itself is empty even if individual ranges would be valid.

Common situations: Computing ranges programmatically (e.g. splitting the hash space across N consumers) when N is 0 or the split logic returns nothing; copying example code but clearing the ranges list; building the policy from empty configuration.

Related errors


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