apache/hadoop · error · EOFException
Cannot seek after EOF
Error message
Cannot seek after EOF
What it means
seek() validates the target against the stream's current file length: targetPos > getFileLength() throws EOFException (a sibling guard rejects negative targets, and a closed stream throws 'Stream is closed!'). It fires when the caller seeks to a position computed from a stale, larger length - typically after the file was truncated or when tail logic extrapolates past EOF.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSInputStream.java:1642
if (n > 0) {
long curPos = getPos();
long fileLen = getFileLength();
if (n+curPos > fileLen) {
n = fileLen - curPos;
}
seek(curPos+n);
return n;
}
return n < 0 ? -1 : 0;
}
/**
* Seek to a new arbitrary location
*/
@Override
public synchronized void seek(long targetPos) throws IOException {
if (targetPos > getFileLength()) {
throw new EOFException("Cannot seek after EOF");
}
if (targetPos < 0) {
throw new EOFException("Cannot seek to negative offset");
}
if (closed.get()) {
throw new IOException("Stream is closed!");
}
boolean done = false;
if (pos <= targetPos && targetPos <= blockEnd) {
//
// If this seek is to a positive position in the current
// block, and this piece of data might already be lying in
// the TCP buffer, then just eat up the intervening data.
//
int diff = (int)(targetPos - pos);
if (diff <= blockReader.available()) {
try {
pos += blockReader.skip(diff);View on GitHub (pinned to 2add963021)
Solutions
- Clamp the target to the freshly fetched file length before seeking
- Re-stat the file (and re-open if it was truncated/replaced) before seeking to saved offsets
- In tail loops, poll length growth and only seek within [0, currentLength]
Example fix
// before in.seek(savedOffset); // saved when the file was longer // after long len = fs.getFileStatus(path).getLen(); in.seek(Math.min(savedOffset, len));
Defensive patterns
Strategy: validation
Validate before calling
long len = fs.getFileStatus(path).getLen();
if (targetPos > len) {
targetPos = len; // clamp: seek to EOF instead of past it
}
if (targetPos < 0) {
throw new IllegalArgumentException("negative seek: " + targetPos);
}
in.seek(targetPos); Type guard
static boolean isSeekPastEof(IOException e) {
return e instanceof EOFException
&& e.getMessage() != null && e.getMessage().equals("Cannot seek after EOF");
} Try / catch
try {
in.seek(targetPos);
} catch (EOFException e) {
if (isSeekPastEof(e)) {
long len = fs.getFileStatus(path).getLen();
in.seek(Math.min(targetPos, len)); // file shrank: clamp
} else throw e;
} Prevention
- Clamp seek targets to the current file length from a fresh stat
- In tail loops, only seek to positions confirmed by the latest length
- Re-open streams after truncate/rotation events instead of reusing stale offsets
When it happens
Trigger: seek(target) where target exceeds the current length: offsets cached from an earlier, longer version of the file; racing a truncate; index/offset files pointing past the current data extent.
Common situations: Tailing loops that remember an old file length across rotation/truncation; readers using saved checkpoints after external truncation; off-by-one seek to len instead of len-1.
Related errors
- Invalid seek offset: position value (%d) must be between 0 a
- 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/00674b2615467f6d.
Report an issue: GitHub.