{"record":{"id":"dd00cf6e7f28b2c8","repo":"apache/hadoop","slug":"cannot-seek-to-a-negative-offset-dd00cf","errorCode":null,"errorMessage":"Cannot seek to a negative offset","messagePattern":"Cannot seek to a negative offset","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/ByteBufferInputStream.java","lineNumber":107,"sourceCode":"  private void checkOpenState() {\n    Preconditions.checkState(isOpen(),\n        FSExceptionMessages.STREAM_IS_CLOSED);\n  }\n\n  public synchronized int read() throws IOException {\n    if (available() > 0) {\n      return byteBuffer.get() & 0xFF;\n    } else {\n      return -1;\n    }\n  }\n\n  @Override\n  public synchronized long skip(long offset) throws IOException {\n    verifyOpen();\n    long newPos = position() + offset;\n    if (newPos < 0) {\n      throw new EOFException(FSExceptionMessages.NEGATIVE_SEEK);\n    }\n    if (newPos > size) {\n      throw new EOFException(FSExceptionMessages.CANNOT_SEEK_PAST_EOF);\n    }\n    byteBuffer.position((int) newPos);\n    return newPos;\n  }\n\n  @Override\n  public synchronized int available() {\n    checkOpenState();\n    return byteBuffer.remaining();\n  }\n\n  /**\n   * Get the current buffer position.\n   * @return the buffer position\n   */","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/ByteBufferInputStream.java#L89-L125","documentation":"skip(offset) on ByteBufferInputStream computes newPos = position() + offset. If newPos is negative it throws EOFException('Cannot seek to a negative offset'). Unlike java.io.InputStream.skip, negative skips are not silently ignored.","triggerScenarios":"Calling skip with a negative offset larger than the current position (position 3, skip(-10)); computing offsets as (target - current) where target can be below zero.","commonSituations":"Backward-seeking logic ported from RandomAccessFile; integer underflow when offset = target - position with target < position; cursors from external indexes that go below zero.","solutions":["Clamp before skipping: long toSkip = Math.max(0, target - in.position())","Go to the start via position(0)-style repositioning rather than a large negative skip","Validate target >= 0 before computing any skip delta"],"exampleFix":"// before\nlong toSkip = targetPos - in.position(); // may be very negative\nin.skip(toSkip); // EOFException\n\n// after\nlong toSkip = Math.max(0, targetPos - in.position());\nif (toSkip > 0) {\n  in.skip(toSkip);\n}","handlingStrategy":"validation","validationCode":"long target = Math.max(0, requestedPos);\nlong toSkip = target - in.position();\nif (toSkip > 0) {\n  in.skip(toSkip);\n}","typeGuard":null,"tryCatchPattern":"Catch EOFException from skip(); a 'Cannot seek to a negative offset' message means the offset arithmetic is wrong upstream — fix the caller, do not swallow.","preventionTips":["Clamp computed skip deltas to >= 0","Validate target positions before seeking","Use position()-based APIs to move backwards to a known offset"],"tags":["hadoop","io","input-stream","seek","validation"],"backgroundTag":"negative-seek-offset","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}