apache/iceberg · error · EOFException

Cannot seek to position after end of file

Error message

Cannot seek to position after end of file: %s

What it means

SingleBufferInputStream.seek validates the target position against the underlying buffer length and throws EOFException when the position is past the end of the data. It is a seek() called with an offset beyond the readable bytes of the single backing buffer.

Solutions

  1. Validate the target offset against the file/buffer length before seeking (offset must be <= length).
  2. Re-read or re-download the data file — the buffer may be truncated or corrupt.
  3. Check that offsets come from the same file version/snapshot the buffer was read from.
  4. Fix off-by-one logic: last valid seek position equals length, not length + 1 of a record.

Example fix

// before
stream.seek(offset); // may throw EOFException

// after
if (offset <= stream.length()) {
  stream.seek(offset);
} else {
  throw new IllegalStateException("Offset " + offset + " exceeds data length " + stream.length());
}
Defensive patterns

Strategy: validation

Validate before calling

void seekSafe(SingleBufferInputStream in, long pos) throws IOException {
  Preconditions.checkArgument(pos >= 0 && pos <= in.length(),
      "Seek target %s out of range [0, %s]", pos, in.length());
  in.seek(pos);
}

Try / catch

try {
  stream.seek(offset);
} catch (EOFException e) {
  throw new CorruptDataException("Offset " + offset + " past end of data; file likely truncated", e);
}

Prevention

When it happens

Trigger: Calling seek(newPosition) where newPosition > length of the stream, e.g. computing a record offset incorrectly, reading Avro footer/middle offsets against a truncated or shorter buffer, or seeking a relative offset from the wrong base.

Common situations: Corrupt or truncated data files; reading files split at byte boundaries with stale metadata offsets; an off-by-one using file length vs last valid position; deserializing an in-memory Avro buffer with offsets from a different 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/4ff55fb7c647f64c. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/io/SingleBufferInputStream.java:86

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

    int remaining = buffer.remaining();
    if (remaining <= 0) {
      return -1;
    }

    int bytesToRead = Math.min(buffer.remaining(), len);
    buffer.get(bytes, off, bytesToRead);

    return bytesToRead;
  }

  @Override
  public void seek(long newPosition) throws IOException {
    if (newPosition > length) {
      throw new EOFException(
          String.format("Cannot seek to position after end of file: %s", newPosition));
    }

    if (getPos() > newPosition) {
      // backwards seek requires returning to the initial state
      initFromBuffer();
    }

    long bytesToSkip = newPosition - getPos();
    skipFully(bytesToSkip);
  }

  @Override
  public long skip(long len) {
    if (len == 0) {
      return 0;
    }

View on GitHub (pinned to 86d9c8fc54)