{"record":{"id":"850d4c78832c2253","repo":"apache/flink","slug":"negative-duration-is-not-supported","errorCode":null,"errorMessage":"negative duration is not supported","messagePattern":"negative duration is not supported","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/util/TimeUtils.java","lineNumber":87,"sourceCode":"\n        final int len = trimmed.length();\n        int pos = 0;\n\n        char current;\n        while (pos < len && (current = trimmed.charAt(pos)) >= '0' && current <= '9') {\n            pos++;\n        }\n\n        final String number = trimmed.substring(0, pos);\n        final String unitLabel = trimmed.substring(pos).trim().toLowerCase(Locale.US);\n\n        if (number.isEmpty()) {\n            try {\n                // Fall back to parse ISO-8601 duration format\n                Duration parsedDuration = Duration.parse(trimmed);\n                if (parsedDuration.isNegative()) {\n                    // Don't support negative duration which is consistent with before format\n                    throw new NumberFormatException(\"negative duration is not supported\");\n                }\n                return parsedDuration;\n            } catch (DateTimeParseException e) {\n                throw new NumberFormatException(\n                        \"text does not start with a number, and is not a valid ISO-8601 duration format: \"\n                                + trimmed);\n            }\n        }\n\n        final BigInteger value;\n        try {\n            value = new BigInteger(number); // this throws a NumberFormatException\n        } catch (NumberFormatException e) {\n            throw new IllegalArgumentException(\n                    \"The value '\" + number + \"' cannot be represented as an integer number.\", e);\n        }\n\n        final ChronoUnit unit;","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/util/TimeUtils.java#L69-L105","documentation":"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.","triggerScenarios":"Calling TimeUtils.parseDuration(\"-PT30S\"), TimeUtils.parseDuration(\"PT-0.5H\"), or any ISO-8601 string whose resulting Duration.isNegative() is true.","commonSituations":"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.","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."],"exampleFix":"# before\nretry.delay=-PT30S\n\n# after\nretry.delay=30 s","handlingStrategy":"validation","validationCode":"if (text.trim().startsWith(\"-\") || text.contains(\"-P\") && Duration.parse(text).isNegative()) {\n    throw new IllegalArgumentException(\"Negative durations are not allowed: \" + text);\n}\nDuration d = TimeUtils.parseDuration(text);","typeGuard":null,"tryCatchPattern":"try { TimeUtils.parseDuration(text); }\ncatch (NumberFormatException | IllegalArgumentException e) { /* map to user-facing config error */ }","preventionTips":["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."],"tags":["configuration","duration","parsing","validation"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}