apache/flink · error · IllegalArgumentException

Invalid bounds.

Error message

Invalid bounds.

What it means

Thrown by DataInputDeserializer.setBuffer(byte[], int, int) (and the matching constructor) when start is negative, len is negative, or start+len exceeds buffer.length. It clamps the deserialization window so all subsequent reads stay inside the backing byte array.

Source

Thrown at flink-core/src/main/java/org/apache/flink/core/memory/DataInputDeserializer.java:88

            this.end = this.position + buffer.remaining();
        } else if (buffer.isDirect() || buffer.isReadOnly()) {
            // TODO: FLINK-8585 handle readonly and other non array based buffers more efficiently
            // without data copy
            this.buffer = new byte[buffer.remaining()];
            this.position = 0;
            this.end = this.buffer.length;

            buffer.get(this.buffer);
        } else {
            throw new IllegalArgumentException(
                    "The given buffer is neither an array-backed heap ByteBuffer, nor a direct ByteBuffer.");
        }
    }

    public void setBuffer(@Nonnull byte[] buffer, int start, int len) {

        if (start < 0 || len < 0 || start + len > buffer.length) {
            throw new IllegalArgumentException("Invalid bounds.");
        }

        setBufferInternal(buffer, start, len);
    }

    public void setBuffer(@Nonnull byte[] buffer) {
        setBufferInternal(buffer, 0, buffer.length);
    }

    private void setBufferInternal(@Nonnull byte[] buffer, int start, int len) {
        this.buffer = buffer;
        this.position = start;
        this.end = start + len;
    }

    public void releaseArrays() {
        this.buffer = null;
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Validate start>=0, len>=0, and start+len<=buffer.length before calling setBuffer.
  2. Use setBuffer(byte[]) (no offsets) when you intend to read the whole array.
  3. Clamp the length: len = Math.min(requestedLen, buffer.length - start).

Example fix

// before
deserializer.setBuffer(buf, offset, end); // end overshoots

// after
int len = Math.min(end - offset, buf.length - offset);
deserializer.setBuffer(buf, offset, len >= 0 ? len : 0);
Defensive patterns

Strategy: validation

Validate before calling

static boolean validBounds(byte[] buffer, int start, int len) {
    return start >= 0 && len >= 0 && start + len <= buffer.length;
}
// if (validBounds(buf, start, len)) deserializer.setBuffer(buf, start, len);

Prevention

When it happens

Trigger: Calling setBuffer(buffer, start, len) or new DataInputDeserializer(buffer, start, len) with start<0, with len<0, or with start+len greater than buffer.length.

Common situations: Off-by-one when computing length from a position (e.g. passing end instead of end-start); reusing a sub-array with stale offset math; slicing a buffer region with an end index that overshoots the array.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/f823aa52aa369816. Report an issue: GitHub.