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

  1. Clamp the target before seeking: seek(Math.max(0, target)).
  2. 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.
  3. Validate external offsets (CLI args, config) as non-negative and within file length before use.
  4. 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

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


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