{"record":{"id":"2bebda90577bc14e","repo":"apache/pulsar","slug":"keys-and-values-must-be-0","errorCode":null,"errorMessage":"Keys and values must be >= 0","messagePattern":"Keys and values must be >= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/ConcurrentLongLongPairHashMap.java","lineNumber":682,"sourceCode":"        hash += 31 + (key2 * HashMixer);\n        hash ^= hash >>> R;\n        hash *= HashMixer;\n        return hash;\n    }\n\n    static final int signSafeMod(long n, int max) {\n        // as the ITEM_SIZE of Section is 4, so the index is the multiple of 4\n        // that is to left shift 2 bits\n        return (int) (n & (max - 1)) << 2;\n    }\n\n    private static int alignToPowerOfTwo(int n) {\n        return (int) Math.pow(2, 32 - Integer.numberOfLeadingZeros(n - 1));\n    }\n\n    private static void checkBiggerEqualZero(long n) {\n        if (n < 0L) {\n            throw new IllegalArgumentException(\"Keys and values must be >= 0\");\n        }\n    }\n\n    /**\n     * A pair of long values.\n     */\n    public static class LongPair implements Comparable<LongPair> {\n        public final long first;\n        public final long second;\n\n        public LongPair(long first, long second) {\n            this.first = first;\n            this.second = second;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (obj instanceof LongPair) {","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/ConcurrentLongLongPairHashMap.java#L664-L700","documentation":"ConcurrentLongLongPairHashMap only stores non-negative long pairs; checkBiggerEqualZero throws IllegalArgumentException when any key or value passed to put/get/remove-like APIs is negative. This is a documented precondition of the data structure, not an internal fault.","triggerScenarios":"Calling put(k1,v1,k2,v2), get(...), containsKey(...), or remove(...) with any of the four longs being negative.","commonSituations":"Mapping signed values (timestamps before epoch, negative offsets, unsigned-32 values wrapped as negative) into a map designed for non-negative ids only.","solutions":["Check every key/value is >= 0 before calling put/get/remove","If negative values must be stored, offset/encode them into non-negative domain first","Use a different data structure (e.g. HashMap<Long, LongPair>) when negatives are required"],"exampleFix":"// before\nmap.put(a, b, c, d); // a is negative on overflow\n// after\nif (a >= 0 && b >= 0 && c >= 0 && d >= 0) {\n    map.put(a, b, c, d);\n}","handlingStrategy":"validation","validationCode":"static boolean canStore(long k1, long v1, long k2, long v2) {\n    return k1 >= 0 && v1 >= 0 && k2 >= 0 && v2 >= 0;\n}","typeGuard":null,"tryCatchPattern":"try {\n    map.put(k1, v1, k2, v2);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Negative key/value rejected: {}\", e.getMessage());\n}","preventionTips":["Validate inputs at API boundaries before inserting into the map","Avoid -1 sentinels in id fields that feed this structure","Document non-negative domain requirement at call sites"],"tags":["java","illegal-argument","precondition"],"backgroundTag":"negative-key-not-allowed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}