apache/hadoop · error · EOFException

Invalid seek offset: position value (%d) must be between 0 a

Error message

Invalid seek offset: position value (%d) must be between 0 and %d for '%s'

What it means

The second branch of validatePosition throws EOFException when objectSize >= 0 and the requested position is >= objectSize: seeks must land strictly inside [0, objectSize). Seeks to exactly size are rejected even though read() at that point would return -1. gzip-encoded objects never hit this branch because their objectSize is Long.MAX_VALUE.

Source

Thrown at hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageClientReadChannel.java:596

          resourceId.getBucketName(), resourceId.getObjectName(), new IOException(msg, error));
    case OUT_OF_RANGE:
      return (IOException) new EOFException(msg).initCause(error);
    default:
      return new IOException(msg, error);
    }
  }

  /** Validates that the given position is valid for this channel. */
  private void validatePosition(long position) throws IOException {
    if (position < 0) {
      throw new EOFException(
          String.format(
              "Invalid seek offset: position value (%d) must be >= 0 for '%s'",
              position, resourceId));
    }

    if (objectSize >= 0 && position >= objectSize) {
      throw new EOFException(
          String.format(
              "Invalid seek offset: position value (%d) must be between 0 and %d for '%s'",
              position, objectSize, resourceId));
    }
  }

  /** Throws if this channel is not currently open. */
  private void throwIfNotOpen() throws IOException {
    if (!isOpen()) {
      throw new ClosedChannelException();
    }
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Detect EOF by reading (read() == -1) instead of seeking to size; remove seek-to-size idioms.
  2. Refresh file status (getItemInfo/getFileStatus) before computing offsets from size.
  3. Clamp: position = Math.min(position, size - 1) only when a valid read position is actually required.

Example fix

// before
if (hasMoreData) { ch.position(size); } // throws when position >= size

// after
if (hasMoreData) {
  int b = ch.read(ByteBuffer.allocate(1));
  boolean eof = (b == -1);
}
Defensive patterns

Strategy: validation

Validate before calling

long size = ch.size();
if (position >= size) {
  return; // at/after EOF: nothing to seek to
}
ch.position(position);

Prevention

When it happens

Trigger: Calling position(n) / seek with n >= objectSize: readers seeking to end-of-file to force EOF, split computations built from stale FileStatus sizes, or stale channel size after a concurrent overwrite shrank the object.

Common situations: InputSplits computed from outdated listings; frameworks that 'seek to size' as a termination idiom; files replaced by shorter versions while a reader held old metadata.

Related errors


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