MyCATApache/Mycat-Server · error · NumberFormatException

Size must be specified as bytes (b), kibibytes (k)…

Error message

Size must be specified as bytes (b), kibibytes (k), mebibytes (m), gibibytes (g), tebibytes (t), or pebibytes(p). E.g. 50b, 100k, or 250m.
${e.getMessage()}

What it means

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.

Solutions

  1. Use only the accepted suffixes: b, k, m, g, t, p, e.g. "50b", "100k", "250m".
  2. Remove whitespace and any decimal fractions; the numeric part must be a plain long (write 1536m instead of 1.5g).
  3. Pre-validate config strings with JavaUtils.memoryStringToBytes-style regex before passing them in, and surface a clear config error to the user.
  4. Catch NumberFormatException at the config-loading layer and rethrow with the offending property name and raw value.

Example fix

// before
conf.set("memory.size", "512MB");
// after
conf.set("memory.size", "512m");
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern SIZE_RE = Pattern.compile("^([0-9]+)([bBkKmGgTpP])$");
public static boolean isValidSizeString(String s) {
  return s != null && SIZE_RE.matcher(s.trim()).matches();
}
// call JavaUtils.byteStringAsBytes only if isValidSizeString(value)

Try / catch

try { long bytes = JavaUtils.byteStringAsBytes(raw); } catch (NumberFormatException e) { throw new IllegalArgumentException("Bad size config value: " + raw, e); }

Prevention

When it happens

Trigger: 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".

Common situations: 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".

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/cc9069abee59ac76. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/memory/unsafe/utils/JavaUtils.java:223

        if (suffix != null && !byteSuffixes.containsKey(suffix)) {
          throw new NumberFormatException("Invalid suffix: \"" + suffix + "\"");
        }

        // If suffix is valid use that, otherwise none was provided and use the default passed
        return unit.convertFrom(val, suffix != null ? byteSuffixes.get(suffix) : unit);
      } else if (fractionMatcher.matches()) {
        throw new NumberFormatException("Fractional values are not supported. Input was: "
          + fractionMatcher.group(1));
      } else {
        throw new NumberFormatException("Failed to parse byte string: " + str);
      }

    } catch (NumberFormatException e) {
      String byteError = "Size must be specified as bytes (b), " +
        "kibibytes (k), mebibytes (m), gibibytes (g), tebibytes (t), or pebibytes(p). " +
        "E.g. 50b, 100k, or 250m.";

      throw new NumberFormatException(byteError + "\n" + e.getMessage());
    }
  }

  /**
   * Convert a passed byte string (e.g. 50b, 100k, or 250m) to bytes for
   * internal use.
   *
   * If no suffix is provided, the passed number is assumed to be in bytes.
   */
  public static long byteStringAsBytes(String str) {
    return byteStringAs(str, ByteUnit.BYTE);
  }

  /**
   * Convert a passed byte string (e.g. 50b, 100k, or 250m) to kibibytes for
   * internal use.
   *
   * If no suffix is provided, the passed number is assumed to be in kibibytes.

View on GitHub (pinned to 65f8d8beb7)