apache/hadoop · error · EOFException

Cannot seek to a negative offset %s

Error message

Cannot seek to a negative offset %s

What it means

ObjectMultiRangeInputStream is the seekable reader that serves an object through sequential range GETs. seek(pos) rejects negative positions with EOFException carrying FSExceptionMessages.NEGATIVE_SEEK ("Cannot seek to a negative offset <pos>"), mirroring the HDFS/FSDataInputStream contract. Seeking past EOF is allowed (the position is stored and validated lazily on the next read); only negative positions throw.

Source

Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/object/ObjectMultiRangeInputStream.java:81

      ObjectStorage storage,
      String objectKey,
      long contentLength,
      long rangeSize,
      byte[] checksum) {
    this.threadPool = threadPool;
    this.storage = storage;
    this.objectKey = objectKey;
    this.contentLength = contentLength;
    this.rangeSize = rangeSize;
    this.checksum = checksum;

    Preconditions.checkNotNull(checksum, "Checksum should not be null.");
  }

  @Override
  public synchronized void seek(long pos) throws IOException {
    if (pos < 0) {
      throw new EOFException(FSExceptionMessages.NEGATIVE_SEEK + " " + pos);
    }

    if (contentLength <= 0) {
      return;
    }

    nextPos = pos;
  }

  @Override
  public synchronized long getPos() {
    return nextPos;
  }

  @Override
  public synchronized boolean seekToNewSource(long targetPos) throws IOException {
    checkNotClosed();
    return false;

View on GitHub (pinned to 2add963021)

Solutions

  1. Clamp positions to >= 0 before calling seek (Math.max(0, pos))
  2. Fix the offset arithmetic that produced the negative value (usually subtracting a chunk larger than the remaining bytes)
  3. Treat -1 sentinels from length/position APIs as EOF, never as a seek target

Example fix

// before
in.seek(pos);

// after
if (pos < 0) {
  throw new IllegalArgumentException("seek position must be >= 0: " + pos);
}
in.seek(pos);
Defensive patterns

Strategy: validation

Validate before calling

if (pos < 0) {
  throw new IllegalArgumentException("seek position must be >= 0: " + pos);
}
in.seek(pos);

Prevention

When it happens

Trigger: Calling seek() with a negative value: seek(-1) directly, arithmetic like seek(getPos() - n) underflowing, or passing a -1 sentinel from an API that uses -1 to mean 'unknown'.

Common situations: Custom FSDataInputStream wrappers computing relative offsets by subtraction; off-by-one bugs in range loops over file splits; reusing a -1 length/offset result as a position.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/462c3136c1fade8b. Report an issue: GitHub.