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
- Validate the target offset against the file/buffer length before seeking (offset must be <= length).
- Re-read or re-download the data file — the buffer may be truncated or corrupt.
- Check that offsets come from the same file version/snapshot the buffer was read from.
- 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
- Bound every computed seek offset against the stream/buffer length first
- Verify file checksums/sizes after download to catch truncation early
- Ensure metadata offsets come from the same file version being read
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
- Cannot seek to position after end of file
- Cannot seek to position
- Failed to decode partition
- Invalid position
- Invalid position: > stream length
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)