aeron-io/aeron · error · IllegalArgumentException

offset= capacity= length=

Error message

offset= capacity= length=

What it means

DirectBufferVector.validate() throws IllegalArgumentException when the vector's length is negative or length exceeds capacity - offset, i.e. the vector would read past the end of the underlying buffer. Aeron throws this before performing a vectored write to guarantee every vector stays inside its buffer. The message includes offset, capacity and length.

Solutions

  1. Validate length before constructing the vector: require 0 <= length && length <= buffer.capacity() - offset.
  2. Clamp parsed/external length values to the remaining buffer space instead of using them verbatim.
  3. Recheck whether the offset you pass already includes a base offset, causing offset+length to overshoot capacity.

Example fix

// before
int length = messageHeader.frameLength();
DirectBufferVector v = new DirectBufferVector(buffer, offset, length);
// after
int length = Math.min(messageHeader.frameLength(), buffer.capacity() - offset);
if (length < 0) { length = 0; }
DirectBufferVector v = new DirectBufferVector(buffer, offset, length);
Defensive patterns

Strategy: validation

Validate before calling

if (length < 0 || offset > buffer.capacity() - length) {
    throw new IllegalArgumentException("length " + length + " exceeds capacity " + buffer.capacity() + " at offset " + offset);
}

Type guard

boolean fitsInBuffer(MutableDirectBuffer buf, int offset, int length) {
    return buf != null && length >= 0 && offset >= 0 && length <= buf.capacity() - offset;
}

Try / catch

try {
    publication.offer(vectors);
} catch (IllegalArgumentException e) {
    log.error("vector length exceeds buffer bounds", e);
    dropBatch();
}

Prevention

When it happens

Trigger: Calling a vectored publish/offer API with a DirectBufferVector whose length < 0, or whose offset + length exceeds buffer.capacity(). Common when length is computed from a header field (e.g. frame or message length read from data) rather than validated against the buffer size.

Common situations: Trusting a length field parsed from a message or network frame that is corrupt or larger than the buffer; off-by-one in offset/length arithmetic; forgetting that length is relative to the vector's own offset, not buffer start.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/4d6b7584efaed9e5. Report an issue: GitHub.

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/DirectBufferVector.java:153

    /**
     * Ensure the vector is valid for the buffer.
     *
     * @throws NullPointerException if the buffer is null.
     * @throws IllegalArgumentException if the offset is out of range for the buffer.
     * @throws IllegalArgumentException if the length is out of range for the buffer.
     * @return this for a fluent API.
     */
    public DirectBufferVector validate()
    {
        final int capacity = buffer.capacity();
        if (offset < 0 || offset >= capacity)
        {
            throw new IllegalArgumentException("offset=" + offset + " capacity=" + capacity);
        }

        if (length < 0 || length > (capacity - offset))
        {
            throw new IllegalArgumentException("offset=" + offset + " capacity=" + capacity + " length=" + length);
        }

        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
        return "DirectBufferVector{" +
            "buffer=" + buffer +
            ", offset=" + offset +
            ", length=" + length +
            '}';
    }

View on GitHub (pinned to 6d60124e15)