apache/hadoop · error · EOFException

Cannot seek to a negative offset " + targetPos

Error message

Cannot seek to a negative offset " + targetPos

What it means

BosInputStream.seek(long) throws EOFException carrying FSExceptionMessages.NEGATIVE_SEEK plus the target position when targetPos < 0. Note the exception type: Hadoop convention reports a bad seek argument as EOFException even though the input is invalid, and checkNotClosed() has already run, so a closed stream fails with a different message first.

Source

Thrown at hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosInputStream.java:275

      super.close();
    }
  }

  /**
   * Seeks to the specified position in the stream. This
   * performs a lazy seek; the actual stream repositioning
   * happens on the next read.
   *
   * @param targetPos the target position to seek to
   * @throws IOException if an I/O error occurs
   */
  public synchronized void seek(long targetPos)
      throws IOException {
    checkNotClosed();

    // Do not allow negative seek
    if (targetPos < 0) {
      throw new EOFException(
          FSExceptionMessages.NEGATIVE_SEEK
              + " " + targetPos);
    }
    if (targetPos > contentLength) {
      throw new EOFException(
          FSExceptionMessages.CANNOT_SEEK_PAST_EOF
              + " " + targetPos);
    }

    if (this.contentLength <= 0) {
      return;
    }

    // Lazy seek
    nextReadPos = targetPos;
  }

  /**

View on GitHub (pinned to 2add963021)

Solutions

  1. Clamp the target: long p = Math.max(0, targetPos); when negative means 'start of file'
  2. Audit position arithmetic for underflow: if (target < 0) target = 0; before calling seek
  3. Translate upstream -1 sentinels into explicit control flow instead of forwarding them to seek

Example fix

// before
in.seek(pos - delimiterLen); // underflows when pos < delimiterLen

// after
in.seek(Math.max(0, pos - delimiterLen));
Defensive patterns

Strategy: validation

Validate before calling

long safeTarget = Math.max(0, requestedPos);
if (requestedPos < 0) LOG.warn("clamping negative seek {} to 0", requestedPos);
in.seek(safeTarget);

Try / catch

catch (EOFException e) {
  if (e.getMessage() != null && e.getMessage().contains("negative")) {
    in.seek(0); // recover: restart from beginning for this record
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling seek() with a negative value — usually a computed position like (previousLineStart - delimiterLength) that underflows, or a -1 sentinel from an upstream API forwarded straight into seek.

Common situations: Custom RecordReaders that rewind by 'pos - 1' to resync delimiters; long arithmetic where a length exceeds the current position; passing 'not found' sentinels (-1) from index lookups into seek.

Related errors


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