{"record":{"id":"df389209a3f9f13d","repo":"apache/pulsar","slug":"try-to-reserve-release-memory-failed-the-param-me","errorCode":null,"errorMessage":"Try to reserve/release memory failed, the param memorySize is a negative value: ${memorySize}","messagePattern":"Try to reserve/release memory failed, the param memorySize is a negative value: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/MemoryLimitController.java","lineNumber":89,"sourceCode":"            // We allow one request to go over the limit, to make the notification\n            // path simpler and more efficient\n            if (current > memoryLimit && memoryLimit > 0) {\n                return false;\n            }\n\n            if (currentUsage.compareAndSet(current, newUsage)) {\n                checkTrigger(current, newUsage);\n                return true;\n            }\n        }\n    }\n\n    private static void checkPositive(long memorySize) {\n        if (memorySize < 0) {\n            String errorMsg = String.format(\"Try to reserve/release memory failed, the param memorySize\"\n                    + \" is a negative value: %s\", memorySize);\n            log.error(errorMsg);\n            throw new IllegalArgumentException(errorMsg);\n        }\n    }\n\n    private void checkTrigger(long prevUsage, long newUsage) {\n        if (newUsage >= triggerThreshold && prevUsage < triggerThreshold && !triggers.isEmpty()) {\n            if (triggerRunning.compareAndSet(false, true)) {\n                try {\n                    for (Runnable trigger : triggers) {\n                        trigger.run();\n                    }\n                } finally {\n                    triggerRunning.set(false);\n                }\n            }\n        }\n    }\n\n    public void reserveMemory(long size) throws InterruptedException {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/MemoryLimitController.java#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlong size = afterOffset - beforeOffset;\ncontroller.releaseMemory(size);\n// after\nlong size = Math.max(0, afterOffset - beforeOffset);\ncontroller.releaseMemory(size);","handlingStrategy":"validation","validationCode":"long size = computeSize();\nif (size < 0) throw new IllegalStateException(\"computed negative size\");\nmemoryLimitController.reserveMemory(size);","typeGuard":null,"tryCatchPattern":"try {\n  controller.tryReserveMemory(size);\n} catch (IllegalArgumentException e) {\n  // negative size: fix size computation before retrying\n}","preventionTips":["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."],"tags":["pulsar","memory-limit","validation","client"],"backgroundTag":"negative-value-argument","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}