apache/hadoop · error · EOFException
Cannot seek to a negative offset {}
Error message
Cannot seek to a negative offset {} What it means
OBSInputStream.seek first calls checkNotClosed() then rejects negative targets: seek(targetPos < 0) throws EOFException(FSExceptionMessages.NEGATIVE_SEEK + ' ' + targetPos). This matches the Hadoop FSDataInputStream contract that negative seeks are invalid. Note the EOFException type (not IOException subclass of choice one might expect) — catch blocks for EOF during reads will also catch this. When contentLength <= 0 the seek is a no-op after the check, so the error is purely about the caller passing a negative position.
Source
Thrown at hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSInputStream.java:272
streamCurrentPos,
nextReadPos,
threadId,
endTime - startTime
);
}
@Override
public synchronized long getPos() {
return nextReadPos < 0 ? 0 : nextReadPos;
}
@Override
public synchronized void seek(final long targetPos) throws IOException {
checkNotClosed();
// Do not allow negative seek
if (targetPos < 0) {
throw new EOFException(
FSExceptionMessages.NEGATIVE_SEEK + " " + targetPos);
}
if (this.contentLength <= 0) {
return;
}
// Lazy seek
nextReadPos = targetPos;
}
/**
* Seek without raising any exception. This is for use in {@code finally}
* clauses
*
* @param positiveTargetPos a target position which must be positive.
*/
private void seekQuietly(final long positiveTargetPos) {View on GitHub (pinned to 2add963021)
Solutions
- Clamp seek targets: long target = Math.max(0, computedPosition) before calling seek
- Fix the position arithmetic — find where a length/count of -1 (common 'empty' sentinel) leaks into seek
- Unit-test edge splits: empty files, single-byte files, and split boundaries at 0 and contentLength
- Note EOFException is thrown, so don't blanket-catch EOFException around seek+read loops and mislabel it as premature EOF
Example fix
// before long target = currentPos - rewindAmount; // can be negative in.seek(target); // EOFException: Cannot seek to a negative offset -N // after long target = Math.max(0, currentPos - rewindAmount); in.seek(target);
Defensive patterns
Strategy: validation
Validate before calling
long clampedTarget = Math.max(0, computedTarget);
if (clampedTarget != computedTarget) {
LOG.debug("clamped negative seek target {} -> {}", computedTarget, clampedTarget);
}
in.seek(clampedTarget); Try / catch
try {
in.seek(target);
} catch (EOFException e) {
if (String.valueOf(e.getMessage()).startsWith("Cannot seek to a negative offset")) {
in.seek(0); // caller bug: negative position; clamp and continue, and fix the arithmetic
} else {
throw e;
}
} Prevention
- Never pass unchecked arithmetic results to seek()
- Treat -1 length sentinels from empty inputs as distinct from positions
- Remember seek's negative-target failure is an EOFException — don't misread it as EOF data
When it happens
Trigger: fs.open(...).seek(negativeValue), typically from arithmetic that computes target = current - delta without clamping at 0; record readers seeking to (index-1)-based offsets; parquet/orc readers computing row-group starts where an empty-file edge case yields -1.
Common situations: Custom InputFormats deriving split starts from offsets that underflow for the last/empty split; porting code from streams where seek(-x) rewound to 0 silently; off-by-one bugs in position bookkeeping after a skipped header.
Related errors
- Cannot seek to a negative offset
- Unsupported block buffer "{}"
- Attempted to seek or read past the end of the file
- Requested more bytes than destination buffer size: request l
- Cannot seek to a negative offset " + targetPos
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/4907e30406d7bea2.
Report an issue: GitHub.