MyCATApache/Mycat-Server · error · NumberFormatException

Time must be specified as seconds (s), milliseconds (ms)…

Error message

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.
${e.getMessage()}

What it means

This is the user-facing NumberFormatException that timeStringAs throws for ANY duration-parse failure: the message combines the accepted-units help text with the underlying error's message (bad format or bad suffix). It is the error developers actually see from timeStringAsMs/timeStringAsSec.

Solutions

  1. Read the nested message (after the newline) for the precise cause: format mismatch vs invalid suffix.
  2. Fix the value to the documented format: signed integer plus optional s/ms/us/m/min/h/d suffix, e.g. 50s, 100ms, 250us.
  3. Wrap calls with a default if config may be missing or malformed.

Example fix

// before
long sec = JavaUtils.timeStringAsSec(props.getProperty("interval")); // "0.5min"
// after
String raw = props.getProperty("interval", "30s");
long sec = JavaUtils.timeStringAsSec(raw.matches("-?\\d+[a-z]*") ? raw : "30s");
Defensive patterns

Strategy: try-catch

Validate before calling

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

Try / catch

long ms;
try {
  ms = JavaUtils.timeStringAsMs(raw);
} catch (NumberFormatException e) {
  // e.getMessage() contains help text + nested cause after the newline
  logger.warn("Bad duration '{}': {}", raw, e.getMessage());
  ms = defaultMillis;
}

Prevention

When it happens

Trigger: Any invalid duration string reaching timeStringAs: non-matching format ("abc", "1.5s", ""), or unrecognized suffix ("50sec"). The catch block rewraps errors 184/185 with this help text.

Common situations: Mistyped config entries in properties/YAML; unit typos like 'sec', 'msec', 'mins+'; fractional durations; unresolved placeholders like "${timeout}".

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

Appendix: source

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

        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) {
    return timeStringAs(str, TimeUnit.MILLISECONDS);
  }

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

View on GitHub (pinned to 65f8d8beb7)