{"record":{"id":"8eaeedab43fdfde1","repo":"apache/cassandra","slug":"size-must-be-non-negative-size","errorCode":null,"errorMessage":"Size must be non-negative (${size})","messagePattern":"Size must be non-negative \\((.+?)\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/utils/memory/BufferPool.java","lineNumber":939,"sourceCode":"            else\n            {\n                if (logger.isTraceEnabled())\n                    logger.trace(\"Requested buffer size {} has been allocated directly due to lack of capacity\", prettyPrintMemory(size));\n            }\n\n            return allocate(size, BufferType.OFF_HEAP);\n        }\n\n        private ByteBuffer tryGet(int size, boolean sizeIsLowerBound)\n        {\n            LocalPool pool = this;\n            if (size <= tinyLimit)\n            {\n                if (size <= 0)\n                {\n                    if (size == 0)\n                        return EMPTY_BUFFER;\n                    throw new IllegalArgumentException(\"Size must be non-negative (\" + size + ')');\n                }\n\n                pool = tinyPool();\n            }\n            else if (size > NORMAL_CHUNK_SIZE)\n            {\n                metrics.misses.mark();\n                return null;\n            }\n\n            ByteBuffer ret = pool.tryGetInternal(size, sizeIsLowerBound);\n            if (ret != null)\n            {\n                metrics.hits.mark();\n                memoryInUse.inc(ret.capacity());\n            }\n            else\n            {","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/utils/memory/BufferPool.java#L921-L957","documentation":"BufferPool.get() returns an empty buffer for size == 0 but throws IllegalArgumentException for any negative size, since a negative allocation is meaningless. The pool must reject these early rather than compute an invalid chunk size.","triggerScenarios":"Calling BufferPool.get(size) (or get(size, bufferType) / allocate variants) with size < 0, typically from a computed length like a truncated file size, a serialized length field, or a subtraction that went negative.","commonSituations":"Corrupt or malicious on-disk length values; reading past EOF yields -1 fed straight into allocate; integer underflow when sizing read buffers.","solutions":["Validate size >= 0 before calling BufferPool.get; treat negatives as corruption and fail the read.","Clamp: if (size <= 0) use BufferPool.get(0) (EMPTY_BUFFER) instead of passing the negative value.","Fix the upstream length computation (e.g. endOffset - startOffset) that produced the negative value."],"exampleFix":"// before\nByteBuffer buf = BufferPool.get(length);\n// after\nif (length < 0) throw new CorruptFileException(\"negative read length \" + length);\nByteBuffer buf = BufferPool.get(length);","handlingStrategy":"validation","validationCode":"if (size < 0) throw new IllegalArgumentException(\"negative size: \" + size);","typeGuard":null,"tryCatchPattern":"try { return BufferPool.get(size); } catch (IllegalArgumentException e) { throw new CorruptFileException(\"bad buffer size\", e); }","preventionTips":["Validate lengths read from disk/network before allocating buffers.","Guard subtraction-based size computations against underflow."],"tags":["buffer-pool","memory","validation","java"],"backgroundTag":"invalid-argument-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}