apache/flink · error · IllegalArgumentException

Length may not be negative.

Error message

Length may not be negative.

What it means

Thrown by DataInputDeserializer.readFully(byte[], int off, int len) when len is negative. readFully is part of the java.io.DataInput contract; Flink rejects a negative length up front rather than passing it to System.arraycopy, which would otherwise throw a less informative ArrayIndexOutOfBoundsException.

Source

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

    public void readFully(@Nonnull byte[] b) throws IOException {
        readFully(b, 0, b.length);
    }

    @Override
    public void readFully(@Nonnull byte[] b, int off, int len) throws IOException {
        if (len >= 0) {
            if (off <= b.length - len) {
                if (this.position <= this.end - len) {
                    System.arraycopy(this.buffer, position, b, off, len);
                    position += len;
                } else {
                    throw new EOFException();
                }
            } else {
                throw new ArrayIndexOutOfBoundsException();
            }
        } else {
            throw new IllegalArgumentException("Length may not be negative.");
        }
    }

    @Override
    public int readInt() throws IOException {
        if (this.position >= 0 && this.position < this.end - 3) {
            @SuppressWarnings("restriction")
            int value = UNSAFE.getInt(this.buffer, BASE_OFFSET + this.position);
            if (LITTLE_ENDIAN) {
                value = Integer.reverseBytes(value);
            }

            this.position += 4;
            return value;
        } else {
            throw new EOFException();
        }
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Guard len>=0 before invoking readFully; reject or treat as zero bytes.
  2. Prefer the readFully(byte[]) overload when reading into the whole array.
  3. If len comes from the stream, validate/compare against available() first.

Example fix

// before
deserializer.readFully(dst, off, remaining); // remaining may be < 0

// after
if (remaining > 0) {
    deserializer.readFully(dst, off, remaining);
} else if (remaining == 0) {
    // nothing to read
}
Defensive patterns

Strategy: validation

Validate before calling

if (len < 0) {
    throw new IllegalArgumentException("readFully len must be >= 0, got " + len);
}
deserializer.readFully(dst, off, len);

Prevention

When it happens

Trigger: Calling readFully(b, off, len) (or the single-arg readFully(b) won't hit this since it passes b.length) with a negative len argument.

Common situations: len derived from a deserialized size field that was corrupted to a negative value; passing a default -1 sentinel; arithmetic underflow when subtracting a consumed count from a remaining total.

Related errors


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