zhisheng17/flink-learning · error · NumberFormatException

text does not start with a number

Error message

text does not start with a number

What it means

TimeUtils.parseDuration parses strings like '100 ms' or '5 s' into milliseconds. It splits the numeric prefix from the unit suffix; if the text begins with the unit and has no leading number (number.isEmpty()), it throws NumberFormatException('text does not start with a number').

Source

Thrown at flink-learning-core/src/main/java/com/zhisheng/core/utils/TimeUtils.java:56

	public static Duration parseDuration(String text) {
		checkNotNull(text, "text");

		final String trimmed = text.trim();
		checkArgument(!trimmed.isEmpty(), "argument is an empty- or whitespace-only string");

		final int len = trimmed.length();
		int pos = 0;

		char current;
		while (pos < len && (current = trimmed.charAt(pos)) >= '0' && current <= '9') {
			pos++;
		}

		final String number = trimmed.substring(0, pos);
		final String unit = trimmed.substring(pos).trim().toLowerCase(Locale.US);

		if (number.isEmpty()) {
			throw new NumberFormatException("text does not start with a number");
		}

		final long value;
		try {
			value = Long.parseLong(number); // this throws a NumberFormatException on overflow
		} catch (NumberFormatException e) {
			throw new IllegalArgumentException("The value '" + number +
				"' cannot be re represented as 64bit number (numeric overflow).");
		}

		final long multiplier;
		if (unit.isEmpty()) {
			multiplier = 1L;
		} else {
			if (matchTimeUnit(unit, TimeUnit.MILLISECONDS)) {
				multiplier = 1L;
			} else if (matchTimeUnit(unit, TimeUnit.SECONDS)) {
				multiplier = 1000L;

View on GitHub (pinned to d731cee761)

Solutions

  1. Provide a numeric value with the unit, e.g. '5 s' or '100 ms'
  2. Validate the duration string matches a number-then-unit pattern before parsing
  3. Trim and correct the config value; use a plain integer (e.g. '500') if the unit is optional in your context

Example fix

// before
TimeUtils.parseDuration("seconds");
// after
TimeUtils.parseDuration("5 seconds");
Defensive patterns

Strategy: validation

Validate before calling

static boolean isParsableDuration(String text) {
    if (text == null) return false;
    String t = text.trim();
    int i = 0;
    if (i < t.length() && (t.charAt(i) == '+' || t.charAt(i) == '-')) i++;
    return i < t.length() && Character.isDigit(t.charAt(i));
}

Try / catch

try {
    long ms = TimeUtils.parseDuration(text);
} catch (NumberFormatException e) {
    if ("text does not start with a number".equals(e.getMessage())) {
        LOG.warn("Duration '{}' must start with a number, e.g. '5 s'", text);
        ms = defaultValue;
    } else throw e;
}

Prevention

When it happens

Trigger: Calling parseDuration with input such as 'ms', ' s', 'seconds', or any string where the first non-whitespace characters are not digits/sign — the first whitespace-split token is not numeric.

Common situations: Config values written as 'seconds' instead of '5 seconds', units-only typo, empty-ish strings like '-' or non-numeric prefixes in duration settings.

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 zhisheng17/flink-learning@d731cee761 (2026-09-06). Data as JSON: /api/errors/7836c20ea637dde2. Report an issue: GitHub.