apache/hadoop · error · IndexOutOfBoundsException

Invalid read parameters: buf.length=%d, off=%d, len=%d

Error message

Invalid read parameters: buf.length=%d, off=%d, len=%d

What it means

BosInputStream.read(byte[],int,int) validates the caller's buffer parameters before any network I/O and throws IndexOutOfBoundsException (formatted with buf.length, off, len) when off < 0, len < 0, or len > buf.length - off. It mirrors the standard InputStream contract: this is a caller programming error, not an environmental failure, and it happens before lazySeek so nothing is read.

Source

Thrown at hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosInputStream.java:154

   * @throws IOException if an I/O error occurs
   */
  public synchronized int read(
      byte[] buf, int off, int len) throws IOException {
    checkNotClosed();

    if (len == 0) {
      return 0;
    }

    if (this.contentLength == 0
        || (nextReadPos >= contentLength)) {
      return -1;
    }

    // Validate and adjust parameters
    if (off < 0 || len < 0
        || len > buf.length - off) {
      throw new IndexOutOfBoundsException(
          String.format(
              "Invalid read parameters:"
                  + " buf.length=%d, off=%d, len=%d",
              buf.length, off, len));
    }

    try {
      lazySeek(nextReadPos, len);
    } catch (EOFException e) {
      // the end of the file has moved
      return -1;
    }

    int bytesRead;
    try {
      bytesRead = in.read(buf, off, len);
    } catch (EOFException e) {
      onReadFailure(e, len);

View on GitHub (pinned to 2add963021)

Solutions

  1. Clamp before calling: int n = Math.min(len, buf.length - off); and assert off >= 0
  2. Replace hand-rolled loops with InputStream.readNBytes(byte[],int,int)/readAllBytes or DataInputStream, which handle bounds correctly
  3. If the exception fired, fix the caller's arithmetic — the values in the message show exactly which argument is wrong

Example fix

// before
int r = in.read(buf, off, len); // off/len from protocol, unchecked

// after
if (off < 0 || len < 0 || off + len > buf.length) {
  throw new IllegalArgumentException("bad read args");
}
int r = in.read(buf, off, Math.min(len, buf.length - off));
Defensive patterns

Strategy: validation

Validate before calling

static void checkReadArgs(byte[] buf, int off, int len) {
  if (buf == null) throw new NullPointerException("buf");
  if (off < 0 || len < 0 || len > buf.length - off) {
    throw new IllegalArgumentException(
        "off=" + off + " len=" + len + " buf.length=" + buf.length);
  }
}
// call checkReadArgs(buf, off, len) before in.read(buf, off, len)

Try / catch

catch (IndexOutOfBoundsException e) {
  // caller bug: values in the message identify the bad argument; fix at call site, do not retry
  throw new IllegalArgumentException("bad read arguments", e);
}

Prevention

When it happens

Trigger: Calling read(buf, off, len) with a negative offset, negative length, or off+len beyond the buffer: e.g. read(buffer, buffer.length, 1024), or an offset variable that decremented past zero in a hand-rolled read loop.

Common situations: Custom RecordReader/InputFormat bugs; buffered read loops that compute 'remaining' incorrectly; passing a length taken from a header or protocol field without clamping it to the destination buffer size.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/c8d003766e9a4e6f. Report an issue: GitHub.