apache/dubbo · error · IllegalArgumentException
new value {newValue} < 0
Error message
new value {newValue} < 0 What it means
Thrown by AtomicPositiveInteger.set when the new value is negative. AtomicPositiveInteger is a Number whose value space is restricted to non-negative integers (it masks the underlying field with Integer.MAX_VALUE so getAndIncrement wraps without going negative). The set() mutator bypasses masking, so it explicitly rejects negative inputs to preserve the non-negative invariant.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/AtomicPositiveInteger.java:59
public final int getAndDecrement() {
return INDEX_UPDATER.getAndDecrement(this) & Integer.MAX_VALUE;
}
public final int incrementAndGet() {
return INDEX_UPDATER.incrementAndGet(this) & Integer.MAX_VALUE;
}
public final int decrementAndGet() {
return INDEX_UPDATER.decrementAndGet(this) & Integer.MAX_VALUE;
}
public final int get() {
return INDEX_UPDATER.get(this) & Integer.MAX_VALUE;
}
public final void set(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
INDEX_UPDATER.set(this, newValue);
}
public final int getAndSet(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
return INDEX_UPDATER.getAndSet(this, newValue) & Integer.MAX_VALUE;
}
public final int getAndAdd(int delta) {
if (delta < 0) {
throw new IllegalArgumentException("delta " + delta + " < 0");
}
return INDEX_UPDATER.getAndAdd(this, delta) & Integer.MAX_VALUE;
}
View on GitHub (pinned to 3a3043227f)
Solutions
- Check the value is >= 0 before calling set(); if it can be negative by design, clamp or mask with (v & Integer.MAX_VALUE).
- Trace the caller computing newValue — usually an off-by-one or unsigned-math bug.
- Use getAndSet only after the same non-negative validation if you also need the previous value.
Example fix
// before api.set(computedIndex); // computedIndex may be -1 // after if (computedIndex < 0) computedIndex = 0; api.set(computedIndex);
Defensive patterns
Strategy: validation
Validate before calling
int newValue = /* ... */; if (newValue < 0) newValue = 0; api.set(newValue);
Type guard
static boolean isNonNegative(int v) { return v >= 0; } Prevention
- Validate the value is >= 0 before calling set().
- Audit index-arithmetic callers for sign errors.
- If negatives are legitimate, use AtomicInteger instead.
When it happens
Trigger: AtomicPositiveInteger.set(newValue) where newValue < 0. Used internally by Dubbo for round-robin / index selection in load balancers; any code path that resets the counter to a negative value triggers it.
Common situations: A load-balancer or selector that computes a starting index arithmetically and passes a negative result (overflow, bad modulo, wrong sign) to set(). Uncommon in normal operation; indicates a logic bug in the caller.
Related errors
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/4c9b2dc4e2c77466.
Report an issue: GitHub.