apache/dubbo · error · IllegalArgumentException
Negative initial size: ${size}
Error message
Negative initial size: ${size} What it means
Thrown by the UnsafeByteArrayOutputStream(int size) constructor when `size` is negative. The constructor allocates `new byte[size]`, which the JVM would reject with NegativeArraySizeException; Dubbo pre-validates and raises IllegalArgumentException("Negative initial size: " + size) with a clearer message. The no-arg constructor delegates to this(32) and never triggers it.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/UnsafeByteArrayOutputStream.java:38
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
/**
* UnsafeByteArrayOutputStream.
*/
public class UnsafeByteArrayOutputStream extends OutputStream {
protected byte[] mBuffer;
protected int mCount;
public UnsafeByteArrayOutputStream() {
this(32);
}
public UnsafeByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: " + size);
}
mBuffer = new byte[size];
}
@Override
public void write(int b) {
int newCount = mCount + 1;
if (newCount > mBuffer.length) {
mBuffer = Bytes.copyOf(mBuffer, Math.max(mBuffer.length << 1, newCount));
}
mBuffer[mCount] = (byte) b;
mCount = newCount;
}
@Override
public void write(byte[] b, int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();View on GitHub (pinned to 3a3043227f)
Solutions
- Use the no-arg constructor new UnsafeByteArrayOutputStream() (defaults to 32) when you have no concrete capacity estimate.
- Clamp the capacity: new UnsafeByteArrayOutputStream(Math.max(0, computedSize)).
- Precondition the producer of the size value so a negative capacity is surfaced at its source.
Example fix
// before new UnsafeByteArrayOutputStream(expected - current); // negative when current > expected // after new UnsafeByteArrayOutputStream(Math.max(0, expected - current));
Defensive patterns
Strategy: validation
Validate before calling
int cap = Math.max(0, expected - current); UnsafeByteArrayOutputStream out = new UnsafeByteArrayOutputStream(cap);
Try / catch
try {
new UnsafeByteArrayOutputStream(size);
} catch (IllegalArgumentException e) {
new UnsafeByteArrayOutputStream(); // fall back to default cap of 32
} Prevention
- Use the no-arg constructor when you have no concrete capacity estimate.
- Clamp computed capacities with Math.max(0, value).
- Never pass a -1 sentinel as a capacity.
When it happens
Trigger: Calling new UnsafeByteArrayOutputStream(size) with size < 0; passing a capacity computed as a - b where a < b; passing a length/size field that was never initialized (default may be 0, but a -1 sentinel triggers it).
Common situations: A configured/derived initial capacity that went negative due to an arithmetic underflow; passing a 'remaining bytes' value that is negative when the buffer is already larger; copy-paste of -1 default sentinel into a capacity argument.
Related errors
- Mark buffer is full!
- should mark before reset!
- unterminated escape sequence at index ${i} of: ${str}
- type [ ${type} ] is unsupported
- bytes2base64: length < 0, length is {}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/4f91820a247bdbe8.
Report an issue: GitHub.