apache/pulsar · error · IllegalArgumentException

Keys and values must be >= 0

Error message

Keys and values must be >= 0

What it means

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.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/ConcurrentLongLongPairHashMap.java:682

        hash += 31 + (key2 * HashMixer);
        hash ^= hash >>> R;
        hash *= HashMixer;
        return hash;
    }

    static final int signSafeMod(long n, int max) {
        // as the ITEM_SIZE of Section is 4, so the index is the multiple of 4
        // that is to left shift 2 bits
        return (int) (n & (max - 1)) << 2;
    }

    private static int alignToPowerOfTwo(int n) {
        return (int) Math.pow(2, 32 - Integer.numberOfLeadingZeros(n - 1));
    }

    private static void checkBiggerEqualZero(long n) {
        if (n < 0L) {
            throw new IllegalArgumentException("Keys and values must be >= 0");
        }
    }

    /**
     * A pair of long values.
     */
    public static class LongPair implements Comparable<LongPair> {
        public final long first;
        public final long second;

        public LongPair(long first, long second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof LongPair) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Check every key/value is >= 0 before calling put/get/remove
  2. If negative values must be stored, offset/encode them into non-negative domain first
  3. Use a different data structure (e.g. HashMap<Long, LongPair>) when negatives are required

Example fix

// before
map.put(a, b, c, d); // a is negative on overflow
// after
if (a >= 0 && b >= 0 && c >= 0 && d >= 0) {
    map.put(a, b, c, d);
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean canStore(long k1, long v1, long k2, long v2) {
    return k1 >= 0 && v1 >= 0 && k2 >= 0 && v2 >= 0;
}

Try / catch

try {
    map.put(k1, v1, k2, v2);
} catch (IllegalArgumentException e) {
    log.warn("Negative key/value rejected: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling put(k1,v1,k2,v2), get(...), containsKey(...), or remove(...) with any of the four longs being negative.

Common situations: Mapping signed values (timestamps before epoch, negative offsets, unsigned-32 values wrapped as negative) into a map designed for non-negative ids only.

Related errors


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