{"record":{"id":"ad8ccac340928665","repo":"apache/hadoop","slug":"cannot-seek-to-a-negative-offset-ad8cca","errorCode":null,"errorMessage":"Cannot seek to a negative offset","messagePattern":"Cannot seek to a negative offset","errorType":"validation","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsInputStream.java","lineNumber":776,"sourceCode":"    if (statistics != null) {\n      statistics.incrementReadOps(1);\n    }\n  }\n\n  /**\n   * Seek to given position in stream.\n   * @param n position to seek to\n   * @throws IOException if there is an error\n   * @throws EOFException if attempting to seek past end of file\n   */\n  @Override\n  public synchronized void seek(long n) throws IOException {\n    LOG.debug(\"requested seek to position {}\", n);\n    if (closed) {\n      throw new IOException(FSExceptionMessages.STREAM_IS_CLOSED);\n    }\n    if (n < 0) {\n      throw new EOFException(FSExceptionMessages.NEGATIVE_SEEK);\n    }\n    if (n > contentLength) {\n      throw new EOFException(FSExceptionMessages.CANNOT_SEEK_PAST_EOF);\n    }\n\n    if (streamStatistics != null) {\n      streamStatistics.seek(n, fCursor);\n    }\n\n    // next read will read from here\n    nextReadPos = n;\n    LOG.debug(\"set nextReadPos to {}\", nextReadPos);\n  }\n\n  @Override\n  public synchronized long skip(long n) throws IOException {\n    if (closed) {\n      throw new IOException(FSExceptionMessages.STREAM_IS_CLOSED);","sourceCodeStart":758,"sourceCodeEnd":794,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsInputStream.java#L758-L794","documentation":"AbfsInputStream.seek(long n) throws EOFException(FSExceptionMessages.NEGATIVE_SEEK, \"Cannot seek to a negative offset\") when n < 0. The check runs after the closed-stream check and before any state changes, so the stream position (nextReadPos) is untouched. It is an argument-validation failure, not an I/O problem.","triggerScenarios":"seek(getPos() - delta) where delta is larger than the current position (rewind past start); passing -1 as a 'reset to beginning' sentinel; computing offsets in int arithmetic that overflows to a negative value then widening to long; upstream parsers handing through a negative byte offset.","commonSituations":"Backward-seeking parsers (e.g., re-reading a record header) that underflow at position 0; porting code that used mark/reset semantics and emulates them with seek(pos - n); int-to-long conversion bugs in offset math on files larger than 2GB.","solutions":["Clamp the target before calling seek: long target = Math.max(0, desiredPos)","Audit every seek argument and assert desiredPos >= 0 in debug builds","Do offset arithmetic in long, never int, to avoid overflow producing negatives"],"exampleFix":"// before\nlong backoff = headerLen; // headerLen > current pos at file start\nin.seek(in.getPos() - backoff);   // EOFException: negative seek\n\n// after\nlong target = Math.max(0, in.getPos() - backoff);\nin.seek(target);","handlingStrategy":"validation","validationCode":"// Clamp and type-check offsets before seeking\nlong safeSeek(FSDataInputStream in, long pos) throws IOException {\n  if (pos < 0) pos = 0;                 // never seek negative\n  in.seek(pos);\n  return pos;\n}","typeGuard":null,"tryCatchPattern":"try {\n  in.seek(desired);\n} catch (EOFException e) {\n  if (desired < 0) {\n    in.seek(0);                          // fall back to file start\n  } else {\n    throw e;                             // genuine EOF problem\n  }\n}","preventionTips":["Do all byte-offset arithmetic in long, never int","Compute relative seeks as Math.max(0, getPos() - backoff)","Reject negative offsets at your API boundary before they reach the stream"],"tags":["azure-blob","abfs","seek","negative-offset","argument-validation"],"backgroundTag":"negative-seek-offset","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}