{"record":{"id":"1bbfb9ea9bb8334b","repo":"apache/hadoop","slug":"position-is-negative-in-range-range","errorCode":null,"errorMessage":"position is negative in range {range}","messagePattern":"position is negative in range (.+?)","errorType":"validation","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/VectoredReadUtils.java","lineNumber":83,"sourceCode":"\n  /**\n   * Validate a single range.\n   * @param range range to validate.\n   * @return the range.\n   * @param <T> range type\n   * @throws IllegalArgumentException the range length is negative or other invalid condition\n   * is met other than the those which raise EOFException or NullPointerException.\n   * @throws EOFException the range offset is negative\n   * @throws NullPointerException if the range is null.\n   */\n  public static <T extends FileRange> T validateRangeRequest(T range)\n          throws EOFException {\n\n    requireNonNull(range, \"range is null\");\n\n    checkArgument(range.getLength() >= 0, \"length is negative in %s\", range);\n    if (range.getOffset() < 0) {\n      throw new EOFException(\"position is negative in range \" + range);\n    }\n    return range;\n  }\n\n  /**\n   * Validate a list of vectored read ranges.\n   * @param ranges list of ranges.\n   * @throws EOFException any EOF exception.\n   */\n  public static void validateVectoredReadRanges(List<? extends FileRange> ranges)\n          throws EOFException {\n    validateAndSortRanges(ranges, Optional.empty());\n  }\n\n  /**\n   * This is the default implementation which iterates through the ranges\n   * to read each synchronously, but the intent is that subclasses\n   * can make more efficient readers.","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/VectoredReadUtils.java#L65-L101","documentation":"Thrown by VectoredReadUtils.validateRangeRequest when a FileRange submitted to a vectored read has a negative offset. Per the method's contract (and slightly unusually), a negative offset raises EOFException while a negative length raises IllegalArgumentException. Validation runs inside validateAndSortRanges/readVectored before any I/O, so this always indicates a caller bug constructing ranges, not a stream condition.","triggerScenarios":"fs.readVectored(stream, ranges) / validateVectoredReadRanges where a FileRange was built with offset < 0: chunk-offset arithmetic underflow (index * chunkSize - delta), signed overflow of a long computed from an int, or parsing a negative offset from user input.","commonSituations":"Custom columnar/parquet readers computing stripe offsets; unit tests generating ranges at boundaries; code ported from an API where negative offsets wrapped around.","solutions":["Fix the range construction: clamp or reject offsets < 0 before creating FileRange objects","Check intermediate arithmetic for underflow (use Math.max(0, pos - delta)) and for int-to-long sign extension","Validate the whole list up front with VectoredReadUtils.validateVectoredReadRanges so failures surface at range-build time with full context"],"exampleFix":"// before\nlong offset = index * chunkSize - delta; // may go negative\nFileRange r = FileRange.createFileRange(offset, len);\n\n// after\nlong offset = Math.max(0L, index * chunkSize - delta);\nif (offset < 0L || len < 0) {\n  throw new IllegalArgumentException(\"Invalid range: offset=\" + offset + \" len=\" + len);\n}\nFileRange r = FileRange.createFileRange(offset, len);","handlingStrategy":"validation","validationCode":"static boolean isValidRange(long offset, int len) {\n  return offset >= 0 && len >= 0;\n}\n\nList<FileRange> safe = new ArrayList<>();\nfor (FileRange r : ranges) {\n  if (isValidRange(r.getOffset(), r.getLength())) {\n    safe.add(r);\n  } else {\n    throw new IllegalArgumentException(\"Bad range: offset=\" + r.getOffset()\n        + \" len=\" + r.getLength());\n  }\n}\nfs.readVectored(f, safe, allocate);","typeGuard":null,"tryCatchPattern":"try {\n  VectoredReadUtils.validateVectoredReadRanges(ranges);\n} catch (EOFException e) {\n  // \"position is negative in range ...\" -> range-construction bug upstream\n  throw new IllegalArgumentException(\"Ranges built with negative offset\", e);\n} catch (IllegalArgumentException e) {\n  // negative length or overlapping ranges\n  throw e;\n}","preventionTips":["Validate offsets/lengths at FileRange construction time, not at read time","Unit-test chunk arithmetic at boundaries (offset 0, first/last chunk) with property-based tests","Remember the contract: negative offset -> EOFException, negative length -> IllegalArgumentException"],"tags":["hadoop","vectored-read","filerange","validation"],"backgroundTag":"invalid-read-offset","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}