apache/hadoop · error · EOFException
Attempted to seek or read past the end of the file " + targe
Error message
Attempted to seek or read past the end of the file " + targetPos
What it means
seek() throws EOFException with FSExceptionMessages.CANNOT_SEEK_PAST_EOF plus the target when targetPos > contentLength, using the object size captured when the stream was opened. No read is attempted. Because the bound is the cached contentLength, a stale view of a concurrently rewritten (smaller) object also triggers it. Note the check is strict '>': seeking exactly to length is allowed and returns EOF on the next read.
Source
Thrown at hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosInputStream.java:280
* Seeks to the specified position in the stream. This
* performs a lazy seek; the actual stream repositioning
* happens on the next read.
*
* @param targetPos the target position to seek to
* @throws IOException if an I/O error occurs
*/
public synchronized void seek(long targetPos)
throws IOException {
checkNotClosed();
// Do not allow negative seek
if (targetPos < 0) {
throw new EOFException(
FSExceptionMessages.NEGATIVE_SEEK
+ " " + targetPos);
}
if (targetPos > contentLength) {
throw new EOFException(
FSExceptionMessages.CANNOT_SEEK_PAST_EOF
+ " " + targetPos);
}
if (this.contentLength <= 0) {
return;
}
// Lazy seek
nextReadPos = targetPos;
}
/**
* Returns the current position in the stream.
*
* @return the current position
* @throws IOException if an I/O error occurs
*/View on GitHub (pinned to 2add963021)
Solutions
- Re-stat the path (fs.getFileStatus) immediately before open() if concurrent writes are possible, and open a fresh stream
- Clamp the target to contentLength and treat read() == -1 as the end-of-file signal instead of seeking past it
- Ensure writers write once to a new key (rename/copy-then-swap) so readers never see a shrinking object
Example fix
// before in.seek(offsetFromStaleMetadata); // after long len = fs.getFileStatus(path).getLen(); in.seek(Math.min(offsetFromStaleMetadata, len));
Defensive patterns
Strategy: validation
Validate before calling
long len = fs.getFileStatus(path).getLen(); // fresh length in.seek(Math.min(targetPos, len));
Try / catch
catch (EOFException e) {
if (e.getMessage() != null && e.getMessage().contains("past the end")) {
// object shrank or position is stale: re-stat and reopen
reopenFrom(fs.getFileStatus(path).getLen());
} else { throw e; }
} Prevention
- Re-stat files before opening when concurrent rewrites are possible
- Writers use new keys per version (copy-then-swap), never truncate in place
- Treat read() == -1 as EOF instead of seeking past the known length
When it happens
Trigger: Seeking to a position derived from a different or older version of the object; a file that was overwritten with a shorter one between open() and seek(); off-by-one logic that treats length+1 as 'one past end'.
Common situations: Reading files that writers rewrite in place (violating immutability expectations); lengths cached from FileStatus before an overwrite; format readers computing end positions from separately-fetched metadata.
Related errors
- Cannot seek to a negative offset " + targetPos
- Attempted to seek or read past the end of the file
- Attempted to seek or read past the end of the file
- Invalid read parameters: buf.length=%d, off=%d, len=%d
- key + ": Stream is closed!"
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/832c94cae298f5bd.
Report an issue: GitHub.