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

  1. Use the no-arg constructor new UnsafeByteArrayOutputStream() (defaults to 32) when you have no concrete capacity estimate.
  2. Clamp the capacity: new UnsafeByteArrayOutputStream(Math.max(0, computedSize)).
  3. 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

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


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/4f91820a247bdbe8. Report an issue: GitHub.