{"record":{"id":"20e1104ad7ff3675","repo":"apache/pulsar","slug":"key-hash-ranges-with-overlap-between-and","errorCode":null,"errorMessage":"Key hash ranges with overlap between  and ","messagePattern":"Key hash ranges with overlap between  and ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/ReaderBuilderImpl.java","lineNumber":246,"sourceCode":"    @Override\n    public ReaderBuilder<T> readCompacted(boolean readCompacted) {\n        conf.setReadCompacted(readCompacted);\n        return this;\n    }\n\n    @Override\n    public ReaderBuilder<T> keyHashRange(Range... ranges) {\n        checkArgument(ranges != null && ranges.length > 0,\n                \"Cannot specify a null ofr an empty key hash ranges for a reader\");\n        for (int i = 0; i < ranges.length; i++) {\n            Range range1 = ranges[i];\n            if (range1.getStart() < 0 || range1.getEnd() > DEFAULT_HASH_RANGE_SIZE) {\n                throw new IllegalArgumentException(\"Ranges must be [0, 65535] but provided range is \" + range1);\n            }\n            for (int j = 0; j < ranges.length; j++) {\n                Range range2 = ranges[j];\n                if (i != j && range1.intersect(range2) != null) {\n                    throw new IllegalArgumentException(\"Key hash ranges with overlap between \" + range1\n                            + \" and \" + range2);\n                }\n            }\n        }\n        conf.setKeyHashRanges(Arrays.asList(ranges));\n        return this;\n    }\n\n    @Override\n    public ReaderBuilder<T> poolMessages(boolean poolMessages) {\n        conf.setPoolMessages(poolMessages);\n        return this;\n    }\n\n    @Override\n    public ReaderBuilder<T> autoUpdatePartitions(boolean autoUpdate) {\n        this.conf.setAutoUpdatePartitions(autoUpdate);\n        return this;","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ReaderBuilderImpl.java#L228-L264","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nreaderBuilder.keyHashRange(Range.of(0, 32767), Range.of(32767, 65535)); // 32767 overlaps\n// after\nreaderBuilder.keyHashRange(Range.of(0, 32766), Range.of(32767, 65535));","handlingStrategy":"validation","validationCode":"for (int i = 0; i < ranges.length; i++) {\n    for (int j = i + 1; j < ranges.length; j++) {\n        if (ranges[i].intersect(ranges[j]) != null) {\n            throw new IllegalArgumentException(\"Overlapping ranges: \" + ranges[i] + \" and \" + ranges[j]);\n        }\n    }\n}","typeGuard":"boolean areDisjoint(Range... ranges) {\n    for (int i = 0; i < ranges.length; i++)\n        for (int j = i + 1; j < ranges.length; j++)\n            if (ranges[i].intersect(ranges[j]) != null) return false;\n    return true;\n}","tryCatchPattern":"try {\n    readerBuilder.keyHashRange(ranges);\n} catch (IllegalArgumentException e) {\n    log.error(\"Overlapping key hash ranges: {}\", e.getMessage());\n    throw new ConfigurationException(\"Key hash ranges must be disjoint\", e);\n}","preventionTips":["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"],"tags":["java","pulsar-client","range-validation","illegal-argument"],"backgroundTag":"overlapping-ranges","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}