apache/hadoop · error · EOFException
Invalid seek offset: position value (%d) must be between 0 a
Error message
Invalid seek offset: position value (%d) must be between 0 and %d for '%s'
What it means
The second branch of validatePosition throws EOFException when objectSize >= 0 and the requested position is >= objectSize: seeks must land strictly inside [0, objectSize). Seeks to exactly size are rejected even though read() at that point would return -1. gzip-encoded objects never hit this branch because their objectSize is Long.MAX_VALUE.
Source
Thrown at hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageClientReadChannel.java:596
resourceId.getBucketName(), resourceId.getObjectName(), new IOException(msg, error));
case OUT_OF_RANGE:
return (IOException) new EOFException(msg).initCause(error);
default:
return new IOException(msg, error);
}
}
/** Validates that the given position is valid for this channel. */
private void validatePosition(long position) throws IOException {
if (position < 0) {
throw new EOFException(
String.format(
"Invalid seek offset: position value (%d) must be >= 0 for '%s'",
position, resourceId));
}
if (objectSize >= 0 && position >= objectSize) {
throw new EOFException(
String.format(
"Invalid seek offset: position value (%d) must be between 0 and %d for '%s'",
position, objectSize, resourceId));
}
}
/** Throws if this channel is not currently open. */
private void throwIfNotOpen() throws IOException {
if (!isOpen()) {
throw new ClosedChannelException();
}
}
}
View on GitHub (pinned to 2add963021)
Solutions
- Detect EOF by reading (read() == -1) instead of seeking to size; remove seek-to-size idioms.
- Refresh file status (getItemInfo/getFileStatus) before computing offsets from size.
- Clamp: position = Math.min(position, size - 1) only when a valid read position is actually required.
Example fix
// before
if (hasMoreData) { ch.position(size); } // throws when position >= size
// after
if (hasMoreData) {
int b = ch.read(ByteBuffer.allocate(1));
boolean eof = (b == -1);
} Defensive patterns
Strategy: validation
Validate before calling
long size = ch.size();
if (position >= size) {
return; // at/after EOF: nothing to seek to
}
ch.position(position); Prevention
- Use read() == -1 as the EOF signal; never seek to size as a termination idiom.
- Recompute splits from a fresh FileStatus immediately before reading.
- Assume sizes can change under you: re-stat on EOFException mentioning seek offsets.
When it happens
Trigger: Calling position(n) / seek with n >= objectSize: readers seeking to end-of-file to force EOF, split computations built from stale FileStatus sizes, or stale channel size after a concurrent overwrite shrank the object.
Common situations: InputSplits computed from outdated listings; frameworks that 'seek to size' as a termination idiom; files replaced by shorter versions while a reader held old metadata.
Related errors
- Invalid seek offset: position value (%d) must be >= 0 for '%
- Cannot seek after EOF
- Attempted to seek or read past the end of the file
- Attempted to seek or read past the end of the file " + targe
- Attempted to seek or read past the end of the file
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/e889962c2332282e.
Report an issue: GitHub.