aeron-io/aeron · error · IllegalStateException
insufficient capacity: maxCapacity=
Error message
insufficient capacity: maxCapacity=<MAX_CAPACITY> limit=<limit> additionalLength=<additionalLength>
What it means
ensureCapacity throws IllegalStateException when the required capacity (existing data + additionalLength) exceeds MAX_CAPACITY — the builder cannot grow any further because it is capped by maximum int-addressable/allowed size. The message gives maxCapacity, current limit, and the additional bytes requested.
Solutions
- Call reset() when the previous message is fully consumed so the builder reuses space instead of growing unbounded.
- Validate frame/message lengths against an application-level max before appending.
- Fix framing logic if a corrupted stream produces absurd length fields.
- Split the data across multiple BufferBuilder instances or streams if genuinely larger than MAX_CAPACITY.
Example fix
// before
builder.append(buffer, offset, hugeLength); // may exceed MAX_CAPACITY
// after
if (builder.limit() + hugeLength <= BufferBuilder.MAX_CAPACITY) {
builder.append(buffer, offset, hugeLength);
} else {
throw new ProtocolError("message too large: " + hugeLength);
} Defensive patterns
Strategy: try-catch
Validate before calling
if ((long) builder.limit() + additionalLength > BufferBuilder.MAX_CAPACITY) {
throw new MessageTooLargeException("appending " + additionalLength + " would exceed max capacity");
} Try / catch
try {
builder.append(buffer, offset, length);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("insufficient capacity")) {
builder.reset(); // or reject the oversized message
} else throw e;
} Prevention
- reset() the builder between messages/streams
- Enforce an application-level max message size before append
- Validate length fields from the wire — huge lengths often mean framing desync
When it happens
Trigger: Appending (append/ensureCapacity) a chunk that would push total required bytes beyond MAX_CAPACITY; typically after many appends without compaction or with a huge single message.
Common situations: Accumulating messages into a BufferBuilder without resetting between streams; receiving unexpectedly large frames (bad framing/protocol desync) inflating required length; forwarding an untrusted length field from a malformed message.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- EINVAL
- initialCapacity outside range 0
- limit outside range: capacity=
- unknown RES_TYPE=
- Insufficient length:
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/7e5227fca6f75206.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/BufferBuilder.java:271
.fragmentedFrameLength(fragmentedFrameLength);
headerBuffer.putInt(FRAME_LENGTH_FIELD_OFFSET, HEADER_LENGTH + limit, LITTLE_ENDIAN);
// compute complete flags
headerBuffer.putByte(FLAGS_OFFSET, (byte)(headerBuffer.getByte(FLAGS_OFFSET) | header.flags()));
return completeHeader;
}
private void ensureCapacity(final int additionalLength)
{
final long requiredCapacity = (long)limit + additionalLength;
final int capacity = buffer.capacity();
if (requiredCapacity > capacity)
{
if (requiredCapacity > MAX_CAPACITY)
{
throw new IllegalStateException(
"insufficient capacity: maxCapacity=" + MAX_CAPACITY +
" limit=" + limit +
" additionalLength=" + additionalLength);
}
resize(findSuitableCapacity(capacity, requiredCapacity));
}
}
private void resize(final int newCapacity)
{
if (isDirect)
{
final ByteBuffer byteBuffer = newDirectBuffer(newCapacity);
buffer.getBytes(0, byteBuffer, 0, limit);
buffer.wrap(byteBuffer);
}
elseView on GitHub (pinned to 6d60124e15)