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

  1. Call reset() when the previous message is fully consumed so the builder reuses space instead of growing unbounded.
  2. Validate frame/message lengths against an application-level max before appending.
  3. Fix framing logic if a corrupted stream produces absurd length fields.
  4. 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

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


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);
        }
        else

View on GitHub (pinned to 6d60124e15)