MyCATApache/Mycat-Server · error · NumberFormatException

Failed to parse byte string

Error message

Failed to parse byte string: ${str}

What it means

byteStringAs throws this NumberFormatException when the input matches neither the integer-byte pattern nor the fraction pattern — i.e. the string is not a recognizable byte size at all. Like the time parser, the wrapping catch (byteError) appends the accepted units help text.

Solutions

  1. Fix the value to the format: signed integer plus optional b/k/m/g/t/p suffix (e.g. 50b, 100k, 250m), no spaces.
  2. Substitute/remove unresolved ${...} placeholders before parsing.
  3. Guard with a default for missing/empty config values.

Example fix

// before
long bytes = JavaUtils.byteStringAsBytes(props.getProperty("mem")); // ""
// after
String raw = props.getProperty("mem", "512m").trim().replace(" ", "");
long bytes = JavaUtils.byteStringAsBytes(raw);
Defensive patterns

Strategy: validation

Validate before calling

if (raw == null || !raw.trim().replace(" ", "").toLowerCase().matches("-?[0-9]+([a-z]+)?")) {
  raw = "512m"; // safe default
}

Try / catch

long bytes;
try {
  bytes = JavaUtils.byteStringAsBytes(raw);
} catch (NumberFormatException e) {
  logger.warn("Bad byte size '{}': {}", raw, e.getMessage());
  bytes = defaultBytes;
}

Prevention

When it happens

Trigger: Passing empty strings, pure unit-less text ("abc"), values with internal spaces ("100 m"), negative fractional forms outside both patterns, or unresolved placeholders like "${memory}" to byteStringAsBytes/Kb/Mb/Gb.

Common situations: Missing or empty properties entries; placeholders not substituted by the config system; values like "100 MB" with spaces copied from documentation.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

      Matcher m = Pattern.compile("([0-9]+)([a-z]+)?").matcher(lower);
      Matcher fractionMatcher = Pattern.compile("([0-9]+\\.[0-9]+)([a-z]+)?").matcher(lower);

      if (m.matches()) {
        long val = Long.parseLong(m.group(1));
        String suffix = m.group(2);

        // Check for invalid suffixes
        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) {

View on GitHub (pinned to 65f8d8beb7)