apache/hadoop · error · EOFException
Cannot seek to a negative offset
Error message
Cannot seek to a negative offset
What it means
BufferedFSInputStream.seek throws EOFException with FSExceptionMessages.NEGATIVE_SEEK ("Cannot seek to a negative offset") whenever the requested position is negative. Besides passing a literal negative offset, the classic route is arithmetic: skip(n) computes getPos()+n, and with n near Long.MAX_VALUE the sum overflows to a negative value; int-to-long conversion mistakes on files larger than 2 GiB produce the same result.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/BufferedFSInputStream.java:87
}
@Override
public long skip(long n) throws IOException {
if (n <= 0) {
return 0;
}
seek(getPos()+n);
return n;
}
@Override
public void seek(long pos) throws IOException {
if (in == null) {
throw new IOException(FSExceptionMessages.STREAM_IS_CLOSED);
}
if (pos < 0) {
throw new EOFException(FSExceptionMessages.NEGATIVE_SEEK);
}
if (this.pos != this.count) {
// optimize: check if the pos is in the buffer
// This optimization only works if pos != count -- if they are
// equal, it's possible that the previous reads were just
// longer than the total buffer size, and hence skipped the buffer.
long end = ((FSInputStream)in).getPos();
long start = end - count;
if( pos>=start && pos<end) {
this.pos = (int)(pos-start);
return;
}
}
// invalidate buffer
this.pos = 0;
this.count = 0;
View on GitHub (pinned to 2add963021)
Solutions
- Clamp the target before seeking: seek(Math.max(0, target)).
- Use long arithmetic throughout and Math.addExact/subtractExact (or explicit range checks) around offset math so overflow fails loudly instead of silently producing negative values.
- Validate external offsets (CLI args, config) as non-negative and within file length before use.
- Fix skip() call sites that pass huge counts; cap n or check for overflow before calling skip.
Example fix
// before long start = offset - trailingHeaderLen; in.seek(start); // EOFException: Cannot seek to a negative offset // after long start = Math.max(0, offset - trailingHeaderLen); in.seek(start);
Defensive patterns
Strategy: validation
Validate before calling
static long clampSeek(long target, long fileLen) {
if (target < 0) return 0;
return Math.min(target, fileLen);
}
// call: in.seek(clampSeek(offset - headerLen, fileLen)); Try / catch
try {
in.seek(target);
} catch (EOFException e) {
if (FSExceptionMessages.NEGATIVE_SEEK.equals(e.getMessage())) {
throw new IllegalArgumentException("seek target underflow: " + target, e);
}
throw e;
} Prevention
- Use long (never int) for all offset arithmetic on large files
- Wrap sums/differences in Math.addExact/Math.subtractExact so overflow fails loudly
- Validate user/config-supplied offsets as non-negative before use
- Remember skip(n) computes getPos()+n: guard huge n against wraparound
When it happens
Trigger: seek(offset - headerLength) where the subtraction underflows at small offsets; computing positions with int arithmetic and casting to long for >2 GiB files; skip(hugeN) wrapping around through overflow; user-supplied offsets parsed from malformed config without range checks.
Common situations: Split/offset math in custom input formats for files bigger than Integer.MAX_VALUE; seek-back logic like seek(pos - bytesRequested) at file start; tools accepting arbitrary seek offsets from the command line or a manifest.
Related errors
- Cannot seek after EOF
- Stream is closed!
- Cannot seek after EOF
- File check failed
- Cannot seek to a negative offset
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/c1b2e8012ffb11ae.
Report an issue: GitHub.