{"record":{"id":"cc9069abee59ac76","repo":"MyCATApache/Mycat-Server","slug":"size-must-be-specified-as-bytes-b-kibibytes-k","errorCode":null,"errorMessage":"Size must be specified as bytes (b), kibibytes (k), mebibytes (m), gibibytes (g), tebibytes (t), or pebibytes(p). E.g. 50b, 100k, or 250m.\n${e.getMessage()}","messagePattern":"Size must be specified as bytes \\(b\\), kibibytes \\(k\\), mebibytes \\(m\\), gibibytes \\(g\\), tebibytes \\(t\\), or pebibytes\\(p\\)\\. E\\.g\\. 50b, 100k, or 250m\\.\n(.+?)","errorType":"validation","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/memory/unsafe/utils/JavaUtils.java","lineNumber":223,"sourceCode":"        if (suffix != null && !byteSuffixes.containsKey(suffix)) {\n          throw new NumberFormatException(\"Invalid suffix: \\\"\" + suffix + \"\\\"\");\n        }\n\n        // If suffix is valid use that, otherwise none was provided and use the default passed\n        return unit.convertFrom(val, suffix != null ? byteSuffixes.get(suffix) : unit);\n      } else if (fractionMatcher.matches()) {\n        throw new NumberFormatException(\"Fractional values are not supported. Input was: \"\n          + fractionMatcher.group(1));\n      } else {\n        throw new NumberFormatException(\"Failed to parse byte string: \" + str);\n      }\n\n    } catch (NumberFormatException e) {\n      String byteError = \"Size must be specified as bytes (b), \" +\n        \"kibibytes (k), mebibytes (m), gibibytes (g), tebibytes (t), or pebibytes(p). \" +\n        \"E.g. 50b, 100k, or 250m.\";\n\n      throw new NumberFormatException(byteError + \"\\n\" + e.getMessage());\n    }\n  }\n\n  /**\n   * Convert a passed byte string (e.g. 50b, 100k, or 250m) to bytes for\n   * internal use.\n   *\n   * If no suffix is provided, the passed number is assumed to be in bytes.\n   */\n  public static long byteStringAsBytes(String str) {\n    return byteStringAs(str, ByteUnit.BYTE);\n  }\n\n  /**\n   * Convert a passed byte string (e.g. 50b, 100k, or 250m) to kibibytes for\n   * internal use.\n   *\n   * If no suffix is provided, the passed number is assumed to be in kibibytes.","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/memory/unsafe/utils/JavaUtils.java#L205-L241","documentation":"JavaUtils.byteStringAs parses human-readable memory size strings (e.g. \"250m\", \"100k\") into byte counts using a strict regex-plus-unit switch. When the unit suffix is not one of b/k/m/g/t/p (case-insensitive) or the numeric part is malformed, the underlying NumberFormatException is rethrown with this explanatory message prepended. It exists because a bare NumberFormatException would not tell the user which size formats are accepted.","triggerScenarios":"Calling byteStringAs/byteStringAsBytes/byteStringAsKb/byteStringAsMb/byteStringAsGb with a string whose suffix is not b, k, m, g, t, or p (e.g. \"50MB\", \"1.5gb\", \"50 bytes\", \"100\"), or a non-numeric value like \"abcm\".","commonSituations":"Users writing Mycat/Spark-style memory configs with SI units like \"512MB\" or \"1G\" instead of the accepted binary-style suffixes; config values copied from documentation of other tools; whitespace or typos in conf files such as \"2 g\" or \"1024kb\".","solutions":["Use only the accepted suffixes: b, k, m, g, t, p, e.g. \"50b\", \"100k\", \"250m\".","Remove whitespace and any decimal fractions; the numeric part must be a plain long (write 1536m instead of 1.5g).","Pre-validate config strings with JavaUtils.memoryStringToBytes-style regex before passing them in, and surface a clear config error to the user.","Catch NumberFormatException at the config-loading layer and rethrow with the offending property name and raw value."],"exampleFix":"// before\nconf.set(\"memory.size\", \"512MB\");\n// after\nconf.set(\"memory.size\", \"512m\");","handlingStrategy":"validation","validationCode":"private static final Pattern SIZE_RE = Pattern.compile(\"^([0-9]+)([bBkKmGgTpP])$\");\npublic static boolean isValidSizeString(String s) {\n  return s != null && SIZE_RE.matcher(s.trim()).matches();\n}\n// call JavaUtils.byteStringAsBytes only if isValidSizeString(value)","typeGuard":null,"tryCatchPattern":"try { long bytes = JavaUtils.byteStringAsBytes(raw); } catch (NumberFormatException e) { throw new IllegalArgumentException(\"Bad size config value: \" + raw, e); }","preventionTips":["Standardize on b/k/m/g/t/p suffixes in all config files","Reject decimal sizes and whitespace at config load time","Validate all memory strings once at startup, not lazily at use"],"tags":["number-format","config","memory-sizing"],"backgroundTag":"invalid-argument-format","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}