apache/dubbo · error · IllegalArgumentException
Negative buffer size
Error message
Negative buffer size
What it means
Thrown by the UnsafeStringWriter(int size) constructor when size < 0. The writer wraps a single StringBuilder; size is used only as the initial capacity hint passed to new StringBuilder(size). A negative capacity is invalid, so the constructor rejects it immediately rather than letting StringBuilder throw a misleading negative array size exception. The no-arg constructor UnsafeStringWriter() is unaffected.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/UnsafeStringWriter.java:34
*/
package org.apache.dubbo.common.io;
import java.io.IOException;
import java.io.Writer;
/**
* Thread-unsafe StringWriter.
*/
public class UnsafeStringWriter extends Writer {
private final StringBuilder mBuffer;
public UnsafeStringWriter() {
lock = mBuffer = new StringBuilder();
}
public UnsafeStringWriter(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative buffer size");
}
lock = mBuffer = new StringBuilder(size);
}
@Override
public void write(int c) {
mBuffer.append((char) c);
}
@Override
public void write(char[] cs) throws IOException {
mBuffer.append(cs, 0, cs.length);
}
@Override
public void write(char[] cs, int off, int len) throws IOException {
if ((off < 0) || (off > cs.length) || (len < 0) || ((off + len) > cs.length) || ((off + len) < 0)) {View on GitHub (pinned to 3a3043227f)
Solutions
- Pass a non-negative size; if you only need default capacity, use new UnsafeStringWriter() (no size).
- Clamp computed sizes: new UnsafeStringWriter(Math.max(0, estimatedSize)).
- Validate the source config value and reject/repair negative sizes upstream.
- Remember the size is only a capacity hint — the StringBuilder grows as needed, so 0 is always safe.
Example fix
// before new UnsafeStringWriter(contentLength - headerOverhead) // negative when header is larger // after new UnsafeStringWriter(Math.max(0, contentLength - headerOverhead))
Defensive patterns
Strategy: validation
Validate before calling
if (size < 0) {
size = 0; // capacity hint only; StringBuilder grows as needed
}
new UnsafeStringWriter(size); Try / catch
UnsafeStringWriter w;
try {
w = new UnsafeStringWriter(size);
} catch (IllegalArgumentException e) {
if ("Negative buffer size".equals(e.getMessage())) {
w = new UnsafeStringWriter(); // fall back to default capacity
} else {
throw e;
}
} Prevention
- Prefer the no-arg UnsafeStringWriter() unless you have a real capacity estimate.
- Clamp computed sizes with Math.max(0, estimated).
- Validate externally-supplied size config before constructing the writer.
- Remember the size is only a capacity hint — 0 is always safe.
When it happens
Trigger: new UnsafeStringWriter(size) with a negative size argument, e.g. new UnsafeStringWriter(-1). Typically size comes from a computed capacity (estimated payload length, header content-length, buffer config) that underflows to negative.
Common situations: Capacity estimated from a subtraction that goes negative (e.g. totalLen - overhead when overhead > totalLen); reading an untrusted/misconfigured buffer-size property; arithmetic on a length that wraps because of an empty or missing field; defaulting size to -1 as 'unspecified'.
Related errors
- Read-ahead limit < 0
- Mark buffer is full!
- should mark before reset!
- Negative initial size: ${size}
- Stream closed
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/3ddbf31febd40521.
Report an issue: GitHub.