apache/hadoop · error · EOFException
Cannot seek to negative offset
Error message
Cannot seek to negative offset
What it means
DFSStripedInputStream.seek(long) validates the target position before moving the read cursor of an erasure-coded HDFS file: positions past EOF and negative positions are both rejected. A negative targetPos throws EOFException('Cannot seek to negative offset') even though the stream itself is healthy — the value passed in is illegal. The striped reader shares this strictness with the replicated reader (DFSInputStream), because internal stripe buffers are indexed from the file start.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSStripedInputStream.java:360
}
updateReadStatistics(readStatistics, stats.getBytesRead(),
stats.isShortCircuit(), stats.getNetworkDistance());
dfsClient.updateFileSystemReadStats(stats.getNetworkDistance(),
stats.getBytesRead(), readTimeMS);
assert readStatistics.getBlockType() == BlockType.STRIPED;
dfsClient.updateFileSystemECReadStats(stats.getBytesRead());
}
/**
* 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!");
}
if (targetPos <= blockEnd) {
final long targetOffsetInBlk = getOffsetInBlockGroup(targetPos);
if (curStripeRange.include(targetOffsetInBlk)) {
int bufOffset = getStripedBufOffset(targetOffsetInBlk);
curStripeBuf.position(bufOffset);
pos = targetPos;
return;
}
}
pos = targetPos;
blockEnd = -1;
}
private int getStripedBufOffset(long offsetInBlockGroup) {View on GitHub (pinned to 2add963021)
Solutions
- Clamp the computed position before seeking: Math.max(0, targetPos).
- Audit all seek call sites for underflow-prone arithmetic and unchecked indexOf()/lastIndexOf() results.
- Map sentinel values (e.g., -1 meaning 'not found') to a real decision — skip the seek or seek(0) — instead of forwarding them.
- As a safety net, catch EOFException around seek() and log-and-correct rather than failing the whole read job.
Example fix
// before long newPos = currentPos - backTrack; in.seek(newPos); // EOFException when backTrack > currentPos // after long newPos = Math.max(0, currentPos - backTrack); in.seek(newPos);
Defensive patterns
Strategy: validation
Validate before calling
if (targetPos < 0) {
throw new IllegalArgumentException(
"seek position must be >= 0, got " + targetPos);
}
if (targetPos > in.getLen()) { // also avoids 'Cannot seek after EOF'
targetPos = in.getLen();
}
in.seek(targetPos); Try / catch
try {
in.seek(targetPos);
} catch (EOFException e) {
LOG.warn("Invalid seek target {} on {} - resetting to 0", targetPos, path, e);
in.seek(0);
} Prevention
- Never feed indexOf()/lastIndexOf() results into seek() without checking for -1.
- Clamp every computed position: Math.max(0, Math.min(pos, fileLen)).
- Validate both bounds — seek() also throws 'Cannot seek after EOF' for targets past the file length.
When it happens
Trigger: Calling seek(n) with n < 0 on an FSDataInputStream opened from an EC-coded HDFS file. Typical producers: backtracking math like pos - backTrack where backTrack > pos, and passing a -1 sentinel (e.g., the result of String.indexOf()/lastIndexOf()) directly into seek().
Common situations: Custom skip/rewind logic that subtracts from the current position without clamping; index-derived offsets not checked for -1; code ported from APIs where seek wrapped around or was a no-op on bad input.
Related errors
- Cannot seek after EOF
- Stream is closed!
- Stream closed
- Not support enhanced byte buffer access.
- Invalid read parameters: buf.length=%d, off=%d, len=%d
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f8fc884ec9adbdb4.
Report an issue: GitHub.