apache/hadoop · error · EOFException
Cannot seek to a negative offset
Error message
Cannot seek to a negative offset
What it means
CosNInputStream.reopen(position) validates the requested byte position before refilling its read buffer; a negative position raises EOFException('Cannot seek to a negative offset') from FSExceptionMessages.NEGATIVE_SEEK. reopen is driven by seek() and by reads whose target falls outside the current buffer, so offset arithmetic that goes below zero surfaces here. Note seek() also has its own earlier guard, so this site is reached through internal repositioning.
Source
Thrown at hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNInputStream.java:148
this.key = key;
this.fileSize = fileSize;
this.preReadPartSize = conf.getLong(
CosNConfigKeys.READ_AHEAD_BLOCK_SIZE_KEY,
CosNConfigKeys.DEFAULT_READ_AHEAD_BLOCK_SIZE);
this.maxReadPartNumber = conf.getInt(
CosNConfigKeys.READ_AHEAD_QUEUE_SIZE,
CosNConfigKeys.DEFAULT_READ_AHEAD_QUEUE_SIZE);
this.readAheadExecutorService = readAheadExecutorService;
this.readBufferQueue = new ArrayDeque<>(this.maxReadPartNumber);
this.closed = false;
}
private synchronized void reopen(long pos) throws IOException {
long partSize;
if (pos < 0) {
throw new EOFException(FSExceptionMessages.NEGATIVE_SEEK);
} else if (pos > this.fileSize) {
throw new EOFException(FSExceptionMessages.CANNOT_SEEK_PAST_EOF);
} else {
if (pos + this.preReadPartSize > this.fileSize) {
partSize = this.fileSize - pos;
} else {
partSize = this.preReadPartSize;
}
}
this.buffer = null;
boolean isRandomIO = true;
if (pos == this.nextPos) {
isRandomIO = false;
} else {
while (this.readBufferQueue.size() != 0) {
if (this.readBufferQueue.element().getStart() != pos) {View on GitHub (pinned to 2add963021)
Solutions
- Clamp the position: seek(Math.max(0, pos)).
- Log pos before seeking and fix the arithmetic that produces negative values.
- Validate the target against the file length from getFileStatus(p).getLen() before seeking.
Example fix
// before long target = currentPos - headerLen; // may be negative in.seek(target); // EOFException: Cannot seek to a negative offset // after long target = Math.max(0, currentPos - headerLen); in.seek(target);
Defensive patterns
Strategy: validation
Validate before calling
long len = fs.getFileStatus(p).getLen();
if (target < 0) { target = 0; }
if (target > len) { target = len; }
in.seek(target); Type guard
static boolean isNegativeSeek(Throwable t) {
return t instanceof EOFException && t.getMessage() != null
&& t.getMessage().contains('negative');
} Try / catch
try {
in.seek(pos);
} catch (EOFException e) {
if (pos < 0) { in.seek(0); } else { throw e; }
} Prevention
- Clamp seek targets to [0, fileLength] before calling seek
- Log computed offsets in custom readers to catch underflow early
- Treat a negative offset as a bug in caller arithmetic, not transient IO
When it happens
Trigger: Computed offsets like pos - readLen underflowing below zero; skip() combined with seek near the file start; custom RecordReaders deriving split start positions that go negative.
Common situations: Custom input formats computing seek targets (split start minus header length); off-by-one after skip; downstream code assuming getPos() can be rewound arbitrarily.
Related errors
- Cannot seek to a negative offset " + targetPos
- Attempted to seek or read past the end of the file
- Cannot seek to a negative offset
- Attempted to seek or read past the end of the file " + targe
- Null IO stream
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/bd09bd419109b5d0.
Report an issue: GitHub.