{"record":{"id":"b9747e67634e1038","repo":"apache/hadoop","slug":"finishedtimebegin-must-be-greater-than-0","errorCode":null,"errorMessage":"finishedTimeBegin must be greater than 0","messagePattern":"finishedTimeBegin must be greater than 0","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsWebServices.java","lineNumber":241,"sourceCode":"      }\n      if (sEnd < 0) {\n        throw new BadRequestException(\"startedTimeEnd must be greater than 0\");\n      }\n    }\n    if (sBegin != null && sEnd != null && sBegin > sEnd) {\n      throw new BadRequestException(\n          \"startedTimeEnd must be greater than startTimeBegin\");\n    }\n\n    Long fBegin = null;\n    if (finishBegin != null && !finishBegin.isEmpty()) {\n      try {\n        fBegin = Long.parseLong(finishBegin);\n      } catch (NumberFormatException e) {\n        throw new BadRequestException(\"Invalid number format: \" + e.getMessage());\n      }\n      if (fBegin < 0) {\n        throw new BadRequestException(\"finishedTimeBegin must be greater than 0\");\n      }\n    }\n    Long fEnd = null;\n    if (finishEnd != null && !finishEnd.isEmpty()) {\n      try {\n        fEnd = Long.parseLong(finishEnd);\n      } catch (NumberFormatException e) {\n        throw new BadRequestException(\"Invalid number format: \" + e.getMessage());\n      }\n      if (fEnd < 0) {\n        throw new BadRequestException(\"finishedTimeEnd must be greater than 0\");\n      }\n    }\n    if (fBegin != null && fEnd != null && fBegin > fEnd) {\n      throw new BadRequestException(\n          \"finishedTimeEnd must be greater than finishedTimeBegin\");\n    }\n    ","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsWebServices.java#L223-L259","documentation":"Thrown by the JobHistoryServer REST API (HsWebServices.getJobs) when the finishedTimeBegin query parameter parses to a negative long. Like the started-time bounds, the finished-time window filter only accepts non-negative epoch-milliseconds values; a negative lower bound is rejected with HTTP 400. The message says 'greater than 0' but the check is fBegin < 0, so 0 is actually permitted.","triggerScenarios":"GET /ws/v1/history/mapreduce/jobs?finishedTimeBegin=-3600000 — any negative integer for this parameter.","commonSituations":"Using a negative offset to express 'last hour' instead of computing now - 3600000; Defaulting unset numeric fields to -1 in the client and always sending them; Sign errors when subtracting a duration from a base timestamp","solutions":["Send a non-negative epoch-milliseconds value computed as now - windowLength","Omit finishedTimeBegin entirely when you do not want a lower bound","Initialize optional numeric params to null/absent, never -1"],"exampleFix":"// before\nlong fBegin = -3600_000; // meant 'last hour'\n\n// after\nlong fBegin = System.currentTimeMillis() - 3600_000;\n// or omit the parameter when unbounded","handlingStrategy":"validation","validationCode":"Long fBegin = Optional.ofNullable(cfg.get(\"finishedTimeBegin\"))\n    .map(String::trim).filter(s -> !s.isEmpty()).map(Long::parseLong)\n    .filter(v -> v >= 0).orElse(null); // null = omit param","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default optional bounds to absent, not -1","Compute 'last N hours' as now - N*3600000, never as -N*3600000","Add a unit test over your query builder covering negative and non-numeric values"],"tags":["hadoop","mapreduce","jobhistory","rest","http-400","query-param","time-range"],"backgroundTag":"query-param-validation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}