apache/hadoop · error · EOFException

Cannot seek to a negative offset " + pos

Error message

Cannot seek to a negative offset " + pos

What it means

AnalyticsStream is the input stream over Amazon S3 Select (S3A selectQuery) results. Its seek() refuses negative positions with EOFException(FSExceptionMessages.NEGATIVE_SEEK + " " + pos) before delegating to the underlying AmazonS3 Select stream. A negative seek position is always a caller bug.

Source

Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/streams/AnalyticsStream.java:107

    try {
      bytesRead = inputStream.read();
    } catch (IOException ioe) {
      onReadFailure(ioe);
      throw ioe;
    }

    if (bytesRead != -1) {
      incrementBytesRead(1);
    }

    return bytesRead;
  }

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


  @Override
  public synchronized long getPos() {
    if (!closed) {
      lastReadCurrentPos = inputStream.getPos();
    }
    return lastReadCurrentPos;
  }


  /**
   * Reads the last n bytes from the stream into a byte buffer. Blocks until end of stream is
   * reached. Leaves the position of the stream unaltered.

View on GitHub (pinned to 2add963021)

Solutions

  1. Fix the caller: clamp positions to >= 0 before seek() (long offset arithmetic can underflow).
  2. Check FSDataInputStream.getPos() and FileStatus offsets before computing seeks in RecordReaders.
  3. If you need true random access, read the object normally (open()) instead of using a selectQuery result stream.
  4. Catch EOFException defensively and log the requested position to find the bad arithmetic.

Example fix

// before
long target = currentPos - bytesToRewind; // can go negative
stream.seek(target);

// after
long target = Math.max(0, currentPos - bytesToRewind);
stream.seek(target);
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

try {
  in.seek(pos);
} catch (EOFException e) {
  // negative seek is a caller bug: log position and fix computation
  LOG.error("bad seek {}", pos, e);
  throw e;
}

Prevention

When it happens

Trigger: Calling seek(negative) on the FSDataInputStream returned by S3AFileSystem.select(); passing a negative offset computed from a variable (e.g. pos - readLength underflow, a getPos() of -1 sentinel leaking into arithmetic); random-access readers treating the select result as seekable beyond the supported contract.

Common situations: Custom InputFormat/RecordReader computing split starts incorrectly and seeking negative; reusing code that seeks to (currentPos - delta) where delta > currentPos; unit tests poking at seek edges. Note S3 Select results are usually consumed sequentially.

Related errors


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