{"record":{"id":"f503c8b60a9d4234","repo":"apache/hadoop","slug":"length-can-t-be-negative","errorCode":null,"errorMessage":"length can't be negative","messagePattern":"length can't be negative","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/SortedRanges.java","lineNumber":230,"sourceCode":"    while(it.hasNext()) {\n      Range range = it.next();\n      sb.append(range.toString()+\"\\n\");\n    }\n    return sb.toString();\n  }\n  \n  /**\n   * Index Range. Comprises of start index and length.\n   * A Range can be of 0 length also. The Range stores indices \n   * of type long.\n   */\n  public static class Range implements Comparable<Range>, Writable{\n    private long startIndex;\n    private long length;\n        \n    Range(long startIndex, long length) {\n      if(length<0) {\n        throw new RuntimeException(\"length can't be negative\");\n      }\n      this.startIndex = startIndex;\n      this.length = length;\n    }\n    \n    public Range() {\n      this(0,0);\n    }\n    \n    /**\n     * Get the start index. Start index in inclusive.\n     * @return startIndex. \n     */\n    long getStartIndex() {\n      return startIndex;\n    }\n    \n    /**","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/SortedRanges.java#L212-L248","documentation":"SortedRanges.Range represents an inclusive start index plus a length (length 0 allowed) and is used by the skip-bad-records machinery to skip record index ranges. The constructor rejects any negative length with this RuntimeException, because a negative span makes iteration semantics undefined. In practice the bad value almost always comes from range arithmetic on record indices rather than from user configuration directly.","triggerScenarios":"Constructing new Range(start, len) with len < 0 — e.g. subtracting a larger index from a smaller one when computing a skip window, or feeding corrupted skip metadata (from a previous failed attempt) back into SortedRanges.add().","commonSituations":"Skip-mode jobs (mapreduce.map.skip.maxrecords > 0) after an earlier attempt wrote malformed skip information; custom RecordReaders that manipulate SortedRanges; integer overflow when start + length wraps.","solutions":["If this happens with skip-bad-records enabled, disable skip mode for the job (remove mapreduce.map.skip.maxrecords) and clean the job's attempt directories so stale skip data is not reused.","In custom code, validate/clamp the computed length to >= 0 before creating a Range.","Check for long overflow in index arithmetic (start + length) that can wrap negative."],"exampleFix":"// before\nranges.add(new SortedRanges.Range(start, end - cursor)); // can be negative\n\n// after\nlong len = Math.max(0L, end - cursor);\nranges.add(new SortedRanges.Range(start, len));","handlingStrategy":"validation","validationCode":"if (length < 0) {\n  throw new IllegalArgumentException(\"Range length must be >= 0, got \" + length);\n}\nranges.add(new SortedRanges.Range(startIndex, length));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate range arithmetic (end - start) before constructing Range objects.","Guard against long overflow when computing start + length.","Keep skip-mode job directories clean between retries so stale skip data is not reloaded."],"tags":["hadoop","mapreduce","skip-bad-records","validation","runtime-exception"],"backgroundTag":"invalid-range-argument","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}