apache/pulsar · error · IllegalArgumentException
Keys and values must be >= 0
Error message
Keys and values must be >= 0
What it means
ConcurrentLongPairSet stores pairs of non-negative longs; checkBiggerEqualZero throws IllegalArgumentException when any member of a pair passed to add/contains/remove is negative. The set is intentionally restricted to non-negative values.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/ConcurrentLongPairSet.java:681
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 2, so the index is the multiple of 2
// that is to left shift 1 bit
return (int) (n & (max - 1)) << 1;
}
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");
}
}
/**
* Class representing two 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
- Validate both longs are >= 0 before calling the set API
- Replace -1/UNSET sentinels with a presence flag instead of inserting them
- Encode negative domain values into non-negative space before storing
Example fix
// before
set.add(ledgerId, entryId); // ledgerId may be -1 when unset
// after
if (ledgerId >= 0 && entryId >= 0) {
set.add(ledgerId, entryId);
} Defensive patterns
Strategy: validation
Validate before calling
static boolean canStore(long first, long second) {
return first >= 0 && second >= 0;
} Try / catch
try {
set.add(a, b);
} catch (IllegalArgumentException e) {
log.warn("Rejected negative pair in LongPairSet: {}", e.getMessage());
} Prevention
- Clamp or reject negative values upstream of the set
- Replace sentinel -1 with explicit presence flags
- Unit-test boundary values near overflow/underflow
When it happens
Trigger: Calling add(x,y), contains(x,y), or remove(x,y) with x or y < 0.
Common situations: Adding ledger/entry ids or offsets that were computed with signed arithmetic and went negative (underflow, sentinel -1 leak).
Related errors
- Keys and values must be >= 0
- configuredService should not be an instance of SystemTopicBa
- Segment not found
- Both segments must be active
- Segments are not adjacent: ${hashRange1} and ${hashRange2}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/8d9548ac853f08cd.
Report an issue: GitHub.