MyCATApache/Mycat-Server · error · NumberFormatException

Invalid suffix

Error message

Invalid suffix: "${suffix}"

What it means

Thrown by JavaUtils.timeStringAs while converting a duration string (e.g. '50s', '100ms', '250us') to a count in the requested TimeUnit. After the numeric part parses, the optional unit suffix is looked up in a suffix-to-TimeUnit map; if the suffix is unrecognized (or required and absent), a NumberFormatException with this message is raised. It is a configuration-value validation error: the at-fault input is the string suffix embedded in a time configuration value. Use supported suffixes (ns/us/ms/s/m/h/d) or omit the suffix to take the default unit.

Solutions

  1. Rewrite the value using supported suffixes: s, ms, us, m or min, h, d.
  2. Convert unsupported units explicitly (e.g. 2w → 14d).
  3. Check the exception message: the wrapping error (186) repeats the accepted units.

Example fix

// before
long ms = JavaUtils.timeStringAsMs("5sec");
// after
long ms = JavaUtils.timeStringAsMs("5s");
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidTimeSuffix(String s) {
  java.util.regex.Matcher m = java.util.regex.Pattern.compile("-?[0-9]+([a-z]+)?").matcher(s.trim().toLowerCase());
  return m.matches() && (m.group(1) == null || java.util.Arrays.asList("s","ms","us","m","min","h","d").contains(m.group(1)));
}

Try / catch

try {
  long ms = JavaUtils.timeStringAsMs(raw);
} catch (NumberFormatException e) {
  ms = defaultMillis;
}

Prevention

When it happens

Trigger: Passing values like "50sec", "5milliseconds", "2w", "30min" (if min unsupported here — it is supported; e.g. "30mins"), or "1H" is fine due to lowercase but "1 seconds" fails at regex stage; specifically any letters after the number that aren't a known suffix.

Common situations: Writing durations in units the parser doesn't know (weeks, seconds spelled 'sec', 'hrs'); copying config from another system with different duration conventions.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


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

Appendix: source

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

  /**
   * Convert a passed time string (e.g. 50s, 100ms, or 250us) to a time count in the given unit.
   * The unit is also considered the default if the given string does not specify a unit.
   */
  public static long timeStringAs(String str, TimeUnit unit) {
    String lower = str.toLowerCase().trim();

    try {
      Matcher m = Pattern.compile("(-?[0-9]+)([a-z]+)?").matcher(lower);
      if (!m.matches()) {
        throw new NumberFormatException("Failed to parse time string: " + str);
      }

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

      // Check for invalid suffixes
      if (suffix != null && !timeSuffixes.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.convert(val, suffix != null ? timeSuffixes.get(suffix) : unit);
    } catch (NumberFormatException e) {
      String timeError = "Time must be specified as seconds (s), " +
              "milliseconds (ms), microseconds (us), minutes (m or min), hour (h), or day (d). " +
              "E.g. 50s, 100ms, or 250us.";

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

  /**
   * Convert a time parameter such as (50s, 100ms, or 250us) to milliseconds for internal use. If
   * no suffix is provided, the passed number is assumed to be in ms.
   */
  public static long timeStringAsMs(String str) {

View on GitHub (pinned to 65f8d8beb7)