apache/pulsar · error · IllegalArgumentException
Try to reserve/release memory failed, the param memorySize i
Error message
Try to reserve/release memory failed, the param memorySize is a negative value: ${memorySize} What it means
MemoryLimitController tracks client-side memory usage; reserving or releasing a negative byte count would corrupt the accounting, so checkPositive throws IllegalArgumentException (and logs the error) whenever memorySize < 0. Called by reserveMemory, tryReserveMemory, forceReserveMemory and releaseMemory.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/MemoryLimitController.java:89
// We allow one request to go over the limit, to make the notification
// path simpler and more efficient
if (current > memoryLimit && memoryLimit > 0) {
return false;
}
if (currentUsage.compareAndSet(current, newUsage)) {
checkTrigger(current, newUsage);
return true;
}
}
}
private static void checkPositive(long memorySize) {
if (memorySize < 0) {
String errorMsg = String.format("Try to reserve/release memory failed, the param memorySize"
+ " is a negative value: %s", memorySize);
log.error(errorMsg);
throw new IllegalArgumentException(errorMsg);
}
}
private void checkTrigger(long prevUsage, long newUsage) {
if (newUsage >= triggerThreshold && prevUsage < triggerThreshold && !triggers.isEmpty()) {
if (triggerRunning.compareAndSet(false, true)) {
try {
for (Runnable trigger : triggers) {
trigger.run();
}
} finally {
triggerRunning.set(false);
}
}
}
}
public void reserveMemory(long size) throws InterruptedException {View on GitHub (pinned to 820761864e)
Solutions
- Clamp computed sizes to >= 0 before calling reserveMemory/releaseMemory (Math.max(0, size)).
- Fix the size calculation that produces the negative value (check buffer position/remaining ordering).
- If releasing, pass the exact positive size that was originally reserved.
Example fix
// before long size = afterOffset - beforeOffset; controller.releaseMemory(size); // after long size = Math.max(0, afterOffset - beforeOffset); controller.releaseMemory(size);
Defensive patterns
Strategy: validation
Validate before calling
long size = computeSize();
if (size < 0) throw new IllegalStateException("computed negative size");
memoryLimitController.reserveMemory(size); Try / catch
try {
controller.tryReserveMemory(size);
} catch (IllegalArgumentException e) {
// negative size: fix size computation before retrying
} Prevention
- Clamp all computed sizes with Math.max(0, x) before memory accounting calls.
- Release exactly the amount previously reserved.
- Beware int/long underflow and buffer.remaining() after full consumption.
When it happens
Trigger: Calling any memory-limit API with a negative size, typically because a computed size (payload.remaining(), serialized size, difference of offsets) went negative due to an underflow or unhandled empty buffer.
Common situations: Custom producer interceptor computing sizes with int/long underflow; passing buffer.remaining() after the buffer was fully consumed; diff-based accounting (afterSize - beforeSize) on reordered callbacks.
Related errors
- entryFilterNames can't be empty. To remove entry filters use
- The offloadPolicies must be specified for namespace offload.
- The bucket must be specified for namespace offload.
- cluster data is required
- Can not enable for all producers but denies for replicators,
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/df389209a3f9f13d.
Report an issue: GitHub.