apache/iceberg · error · EOFException

Cannot seek to position

Error message

Cannot seek to position <newPos>: exceeds stream length <contents.length>

What it means

EagerInputStream.seek validates the target position and throws EOFException when skipping to newPos goes past the end of the in-memory contents. Since the whole file is already in memory, its length is fixed and seeking beyond it is meaningless.

Solutions

  1. Check newPos against the stream length before seeking.
  2. Recompute the offset — footer/row-group offsets may come from stale metadata.
  3. Re-read the file to get fresh, correct contents.
  4. Fix caller logic that assumes a larger file than the eager buffer holds.

Example fix

// before
stream.seek(offset); // may throw EOFException
// after
if (offset >= 0 && offset < fileSize) {
  stream.seek(offset);
} else {
  throw new IllegalArgumentException("Offset " + offset + " outside file of length " + fileSize);
}
Defensive patterns

Strategy: validation

Validate before calling

if (newPos < 0 || newPos >= file.getLength()) {
  throw new IllegalArgumentException("seek position " + newPos + " out of bounds");
}

Try / catch

try {
  stream.seek(pos);
} catch (EOFException e) {
  throw new IllegalArgumentException("Offset beyond eager buffer", e);
}

Prevention

When it happens

Trigger: Calling seek(newPos) on a stream obtained from EagerInputFile.newStream() where newPos >= contents.length (e.g. trust length of a Parquet footer offset from stale metadata).

Common situations: Corrupted or stale offset/length metadata in file footers; arithmetic bugs computing read positions; reading a truncated in-memory buffer with offsets meant for the full file.

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/53b3c8cfa016dfa4. Report an issue: GitHub.

Appendix: source

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

  private final ByteArrayInputStream delegate;

  EagerInputStream(byte[] contents) {
    Preconditions.checkNotNull(contents, "contents is null");
    this.contents = contents;
    this.delegate = new ByteArrayInputStream(contents);
  }

  @Override
  public long getPos() throws IOException {
    return (long) contents.length - delegate.available();
  }

  @Override
  public void seek(long newPos) throws IOException {
    Preconditions.checkArgument(newPos >= 0, "position is negative: %s", newPos);
    delegate.reset();
    if (skip(newPos) != newPos) {
      throw new EOFException(
          "Cannot seek to position " + newPos + ": exceeds stream length " + contents.length);
    }
  }

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

  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    return delegate.read(b, off, len);
  }

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

View on GitHub (pinned to 86d9c8fc54)