apache/flink · error · NumberFormatException
negative duration is not supported
Error message
negative duration is not supported
What it means
TimeUtils.parseDuration first tries number+unit parsing; when the text starts with no digits it falls back to ISO-8601 (Duration.parse, e.g. "PT-1.5S" or "-PT10S"). A syntactically valid but negative ISO-8601 duration is rejected with this NumberFormatException because the legacy number+unit format never supported negative durations and Flink keeps that invariant.
Source
Thrown at flink-core/src/main/java/org/apache/flink/util/TimeUtils.java:87
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 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;View on GitHub (pinned to 2f3c205e92)
Solutions
- Use a non-negative duration; if the intent was 'indefinitely disabled', use the documented sentinel for that option (often -1 as an integer or a specific value like 0/Integer.MAX_VALUE per the option's docs).
- Validate durations are >= 0 before formatting them into configuration strings.
- If parsing user input, check for a leading '-' and reject with a clear message before calling parseDuration.
Example fix
# before retry.delay=-PT30S # after retry.delay=30 s
Defensive patterns
Strategy: validation
Validate before calling
if (text.trim().startsWith("-") || text.contains("-P") && Duration.parse(text).isNegative()) {
throw new IllegalArgumentException("Negative durations are not allowed: " + text);
}
Duration d = TimeUtils.parseDuration(text); Try / catch
try { TimeUtils.parseDuration(text); }
catch (NumberFormatException | IllegalArgumentException e) { /* map to user-facing config error */ } Prevention
- Reject leading '-' in duration config before parsing.
- Use documented sentinels (0/-1 integers) for 'disabled' options instead of negative durations.
- Validate durations in a config linter.
When it happens
Trigger: Calling TimeUtils.parseDuration("-PT30S"), TimeUtils.parseDuration("PT-0.5H"), or any ISO-8601 string whose resulting Duration.isNegative() is true.
Common situations: Porting config from systems that allow negative timeouts (meaning "infinite" or "disabled"); sign errors in generated config; programmatically building duration strings from possibly-negative variables.
Related errors
- Unsupported serializer type %s for %s
- Value for configuration key='${key}' is not set correctly. E
- text does not start with a number, and is not a valid ISO-86
- The value '${number}' cannot be represented as an integer nu
- Time interval unit label '${unitLabel}' does not match any o
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/850d4c78832c2253.
Report an issue: GitHub.