apache/flink · error · NumberFormatException

text does not start with a number, and is not a valid ISO-86

Error message

text does not start with a number, and is not a valid ISO-8601 duration format: ${trimmed}

What it means

TimeUtils.parseDuration reads a leading run of digits as the numeric part; if that run is empty (text does not start with a number) it tries ISO-8601 via Duration.parse. When that also fails with DateTimeParseException, the text is rejected with this NumberFormatException listing the offending input.

Source

Thrown at flink-core/src/main/java/org/apache/flink/util/TimeUtils.java:91

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

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

        if (number.isEmpty()) {
            try {
                // Fall back to parse ISO-8601 duration format
                Duration parsedDuration = Duration.parse(trimmed);
                if (parsedDuration.isNegative()) {
                    // Don't support negative duration which is consistent with before format
                    throw new NumberFormatException("negative duration is not supported");
                }
                return parsedDuration;
            } catch (DateTimeParseException e) {
                throw new NumberFormatException(
                        "text does not start with a number, and is not a valid ISO-8601 duration format: "
                                + trimmed);
            }
        }

        final BigInteger value;
        try {
            value = new BigInteger(number); // this throws a NumberFormatException
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "The value '" + number + "' cannot be represented as an integer number.", e);
        }

        final ChronoUnit unit;
        if (unitLabel.isEmpty()) {
            unit = ChronoUnit.MILLIS;
        } else {
            unit = LABEL_TO_UNIT_MAP.get(unitLabel);

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Rewrite the value as <number><optional space><unit>, e.g. "10 s", "5 min", "1 h", or a full ISO-8601 duration like "PT10S".
  2. If the value came from a variable, make sure it was not empty or null-coalesced to "".
  3. Check for a missing 'P' prefix when using ISO-8601 form (PT10S, not T10S).

Example fix

# before
checkpoint.interval=ten-seconds

# after
checkpoint.interval=10 s
Defensive patterns

Strategy: validation

Validate before calling

String t = text.trim();
boolean numberFirst = !t.isEmpty() && Character.isDigit(t.charAt(0));
boolean iso = t.startsWith("P");
if (!numberFirst && !iso) throw new IllegalArgumentException("Not a number+unit or ISO-8601 duration: " + t);
TimeUtils.parseDuration(t);

Try / catch

try { TimeUtils.parseDuration(t); }
catch (NumberFormatException e) { return defaultDuration; } // only if a safe default is acceptable

Prevention

When it happens

Trigger: Calling TimeUtils.parseDuration with text that neither starts with a digit nor is valid ISO-8601, e.g. "abc", "ten seconds", " s", "P" (incomplete ISO period), or "T10S" (missing P prefix).

Common situations: Typos in duration config keys ("1sec" vs "1 s" is fine but "sec" alone is not), missing unit prefix P in ISO strings, localized or spelled-out durations, empty string values.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/148c0f0cefdd6cb3. Report an issue: GitHub.