MyCATApache/Mycat-Server · error · NumberFormatException

Fractional values are not supported. Input was

Error message

Fractional values are not supported. Input was: ${value}

What it means

byteStringAs rejects fractional byte sizes. When the input doesn't match the integer pattern but does match the fraction pattern (e.g. "1.5g"), it throws NumberFormatException naming the fractional input, because sizes must be whole numbers in this parser.

Solutions

  1. Rewrite the value as an integer in a smaller unit: 1.5g → 1536m.
  2. Round the value yourself before passing it in.
  3. If fractions are common in your config, pre-normalize them with a helper before calling byteStringAs.

Example fix

// before
long bytes = JavaUtils.byteStringAsBytes("1.5g");
// after
long bytes = JavaUtils.byteStringAsBytes("1536m");
Defensive patterns

Strategy: validation

Validate before calling

if (raw.matches(".*[0-9]\\.[0-9].*")) {
  // fractional size — convert to a smaller unit or reject before parsing
}

Try / catch

try {
  long bytes = JavaUtils.byteStringAsBytes(raw);
} catch (NumberFormatException e) {
  bytes = defaultBytes;
}

Prevention

When it happens

Trigger: Passing decimal values such as "1.5g", "0.5m", "2.75t" to byteStringAs/byteStringAsBytes/byteStringAsKb/Mb/Gb.

Common situations: Config values like "1.5GB" written by users expecting float support; computed strings from other languages that render doubles ("512.0m").

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/64797030b3e32dde. Report an issue: GitHub.

Appendix: source

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

    String lower = str.toLowerCase().trim();

    try {
      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.
   *

View on GitHub (pinned to 65f8d8beb7)