apache/iceberg · error · EOFException

Cannot read bytes at position : exceeds stream length…

Error message

Cannot read <length> bytes at position <pos>: exceeds stream length <contents.length>

What it means

EagerInputStream.readFully throws EOFException when the requested [pos, pos+length) window lies beyond the in-memory contents array. It is a bounds check that prevents partial reads from the fixed-size byte buffer backing the eager stream.

Solutions

  1. Clamp or validate pos and length against the file length before reading.
  2. Refresh the eager contents — the buffer may be stale or truncated (see the incorrect-length error).
  3. Fix the offset/length source (footer metadata) if it points outside the file.
  4. Use the stream's length() to size reads dynamically.

Example fix

// before
stream.readFully(pos, buf, 0, buf.length);
// after
long len = stream.getLength();
long readable = Math.min(buf.length, len - pos);
if (readable <= 0) throw new IllegalArgumentException("pos " + pos + " beyond end of stream");
stream.readFully(pos, buf, 0, (int) readable);
Defensive patterns

Strategy: validation

Validate before calling

long fileLen = stream.getLength();
if (pos < 0 || pos > fileLen || length > fileLen - pos) {
  throw new IllegalArgumentException("Read window out of bounds");
}

Try / catch

try {
  stream.readFully(pos, buf, offset, length);
} catch (EOFException e) {
  LOG.error("Read [{}..{}] beyond length {}", pos, pos + length, contentsLength);
  throw e;
}

Prevention

When it happens

Trigger: Calling readFully(pos, buffer, offset, length) where pos > contents.length or pos + length > contents.length on a stream from EagerInputFile.newStream().

Common situations: Footer parsers requesting ranges beyond a truncated/stale buffer; using offsets from metadata that referenced a larger file; off-by-one or wrong length computations in read loops.

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 apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/acaac2805224ca9e. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/io/EagerInputStream.java:78

    return delegate.read(b, off, len);
  }

  @Override
  public long skip(long n) throws IOException {
    return delegate.skip(n);
  }

  @Override
  public int available() throws IOException {
    return delegate.available();
  }

  @Override
  public void readFully(long pos, byte[] buffer, int offset, int length) throws IOException {
    Preconditions.checkPositionIndexes(offset, offset + length, buffer.length);
    Preconditions.checkArgument(pos >= 0, "position is negative: %s", pos);
    if (pos > contents.length || length > contents.length - pos) {
      throw new EOFException(
          "Cannot read "
              + length
              + " bytes at position "
              + pos
              + ": exceeds stream length "
              + contents.length);
    }
    System.arraycopy(contents, (int) pos, buffer, offset, length);
  }

  @Override
  public int readTail(byte[] buffer, int offset, int length) throws IOException {
    Preconditions.checkPositionIndexes(offset, offset + length, buffer.length);
    int bytesToCopy = Math.min(length, contents.length);
    System.arraycopy(contents, contents.length - bytesToCopy, buffer, offset, bytesToCopy);
    return bytesToCopy;
  }

View on GitHub (pinned to 86d9c8fc54)