{"record":{"id":"4908fef669a0f2e3","repo":"apache/druid","slug":"invalid-format-of-number-s-negative-value-is-no","errorCode":null,"errorMessage":"Invalid format of number: %s. Negative value is not allowed.","messagePattern":"Invalid format of number: (.+?)\\. Negative value is not allowed\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/HumanReadableBytes.java","lineNumber":147,"sourceCode":"   */\n  public static long parse(String number, long nullValue)\n  {\n    if (number == null) {\n      return nullValue;\n    }\n\n    number = number.trim();\n    if (number.length() == 0) {\n      return nullValue;\n    }\n    return parseInner(number);\n  }\n\n  private static long parseInner(String rawNumber)\n  {\n    String number = StringUtils.toLowerCase(rawNumber);\n    if (number.charAt(0) == '-') {\n      throw new IAE(\"Invalid format of number: %s. Negative value is not allowed.\", rawNumber);\n    }\n\n    int lastDigitIndex = number.length() - 1;\n    boolean isBinaryByte = false;\n    char unit = number.charAt(lastDigitIndex--);\n    if (unit == 'b') {\n      //unit ends with 'b' must be format of KiB/MiB/GiB/TiB/PiB, so at least 3 extra characters are required\n      if (lastDigitIndex < 2) {\n        throw new IAE(\"Invalid format of number: %s\", rawNumber);\n      }\n      if (number.charAt(lastDigitIndex--) != 'i') {\n        throw new IAE(\"Invalid format of number: %s\", rawNumber);\n      }\n\n      unit = number.charAt(lastDigitIndex--);\n      isBinaryByte = true;\n    } else if (unit == 'i') {\n      //unit ends with 'i' must be format of Ki/Mi/Gi/Ti/Pi, so at least 2 extra characters are required","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/HumanReadableBytes.java#L129-L165","documentation":"HumanReadableBytes.parse (via parseInner) throws this IllegalArgumentException for values that start with '-'. Negative byte sizes are meaningless in this library, so any signed input is rejected before further parsing.","triggerScenarios":"Calling HumanReadableBytes.parse(\"-100mb\") or any string whose first character after lowercasing is '-'.","commonSituations":"Accidental leading hyphen from concatenating flags and values; templating mistakes producing \"-${SIZE}\"; users expecting signed/relative sizes to be supported.","solutions":["Remove the minus sign and provide a positive size like \"100mb\"","Validate the configured value is non-negative before parsing","Check the templating/concatenation logic that introduced the leading '-'","Catch IAE at config-load time and fail with a clearer message naming the property"],"exampleFix":"// before\nlong bytes = HumanReadableBytes.parse(\"-512mb\");\n// after\nlong bytes = HumanReadableBytes.parse(\"512mb\");","handlingStrategy":"validation","validationCode":"if (raw != null && raw.trim().startsWith(\"-\")) {\n  throw new IllegalArgumentException(\"Byte size must be non-negative: \" + raw);\n}\nlong bytes = HumanReadableBytes.parse(raw);","typeGuard":"static boolean isNonNegativeSize(String s) {\n  return s != null && !s.trim().startsWith(\"-\");\n}","tryCatchPattern":"try {\n  long bytes = HumanReadableBytes.parse(raw);\n} catch (IAE e) {\n  throw new IllegalArgumentException(\"Configured byte size must be positive, got: \" + raw, e);\n}","preventionTips":["Validate sign at config load time with a clear property-name message","Check string-templating that could inject a leading '-'","Never rely on parsing to enforce business constraints like positivity","Show unit formats in UIs accepting size inputs"],"tags":["configuration","parsing","negative-value"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}