{"record":{"id":"619003cb59c65fd6","repo":"elastic/elasticsearch","slug":"failed-to-parse-setting-with-value-as-a-619003","errorCode":null,"errorMessage":"failed to parse setting [{}] with value [{}] as a time value: negative durations are not supported","messagePattern":"failed to parse setting \\[(.+?)\\] with value \\[(.+?)\\] as a time value: negative durations are not supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/core/src/main/java/org/elasticsearch/core/TimeValue.java","lineNumber":416,"sourceCode":"        } else if (normalized.matches(\"-0*1\")) {\n            return TimeValue.MINUS_ONE;\n        } else if (normalized.matches(\"0+\")) {\n            return TimeValue.ZERO;\n        } else {\n            // Missing units:\n            throw new IllegalArgumentException(\n                \"failed to parse setting [\" + settingName + \"] with value [\" + sValue + \"] as a time value: unit is missing or unrecognized\"\n            );\n        }\n    }\n\n    private static long parse(final String initialInput, final String normalized, final String suffix, String settingName) {\n        final String s = normalized.substring(0, normalized.length() - suffix.length()).trim();\n        try {\n            final long value = Long.parseLong(s);\n            if (value < -1) {\n                // -1 is magic, but reject any other negative values\n                throw new IllegalArgumentException(\n                    \"failed to parse setting [\"\n                        + settingName\n                        + \"] with value [\"\n                        + initialInput\n                        + \"] as a time value: negative durations are not supported\"\n                );\n            }\n            return value;\n        } catch (final NumberFormatException e) {\n            try {\n                @SuppressWarnings(\"unused\")\n                final double ignored = Double.parseDouble(s);\n                throw new IllegalArgumentException(\"failed to parse [\" + initialInput + \"], fractional time values are not supported\", e);\n            } catch (final NumberFormatException ignored) {\n                throw new IllegalArgumentException(\"failed to parse [\" + initialInput + \"]\", e);\n            }\n        }\n    }","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/core/src/main/java/org/elasticsearch/core/TimeValue.java#L398-L434","documentation":"Thrown by TimeValue.parse when a setting's numeric component parses as a valid long but is less than -1. The value -1 is reserved as a magic sentinel (typically meaning 'disabled' or 'unbounded'); every other negative duration is rejected because negative time has no meaningful interpretation for a timeout or interval. The error names the setting and echoes the original (un-normalized) input so the offending config line is identifiable.","triggerScenarios":"Calling TimeValue.parseTimeValue (or any setting parser that delegates to it) with input like \"-5s\", \"-100ms\", \"-2h\", or \"-50\". Produced when an index setting, cluster setting, or transport timeout is set to a negative number other than -1. Concretely fires at TimeValue.java:416 after Long.parseLong succeeds with value < -1.","commonSituations":"A user sets a timeout setting (e.g. search.default_search_timeout, transport.connect_timeout) to a negative value by mistake, or a formula/variable that underflows to negative. Copy-pasting a value meant for a different unit. Tooling that injects computed durations without clamping to a minimum.","solutions":["Set the value to a positive duration (e.g. \"30s\", \"5m\") or to -1 if the setting treats -1 as disabled/unbounded.","If the value comes from a computed variable, clamp it: value = Math.max(-1, computed) before formatting the string.","Audit the offending setting name in the error message against elasticsearch.yml or the index/cluster settings API to locate the bad input.","If you genuinely need 'no timeout', use -1 (and confirm the specific setting honors the -1 sentinel — not all do)."],"exampleFix":"// before\nindex.cache.query.size: -5m\n\n// after\nindex.cache.query.size: -1   // -1 = disabled; or a positive duration like 10m","handlingStrategy":"validation","validationCode":"// Validate a candidate time-value string before passing to TimeValue.parseTimeValue\nprivate static final Pattern TV = Pattern.compile(\"^(?:-1|-?\\\\d+)([a-z\\\\u00b5]+)$\");\nvoid check(String s, String setting) {\n    Matcher m = TV.matcher(s.toLowerCase(Locale.ROOT).trim());\n    if (!m.matches()) throw new IllegalArgumentException(\"bad \" + setting + \": \" + s);\n    if (!s.equals(\"-1\")) {\n        long n = Long.parseLong(m.group(0).replaceAll(\"[a-z\\\\u00b5]+$\", \"\"));\n        if (n < -1) throw new IllegalArgumentException(\"negative duration not allowed: \" + s);\n    }\n}","typeGuard":"// Narrow string inputs known to be safe for TimeValue\nstatic boolean isAcceptableDuration(String s) {\n    if (s == null) return false;\n    String n = s.trim().toLowerCase(Locale.ROOT);\n    return n.equals(\"-1\") || n.matches(\"0+\") || n.matches(\"\\\\d+(ns|us|micros|ms|s|m|h|d)\");\n}","tryCatchPattern":"try {\n    TimeValue tv = TimeValue.parseTimeValue(raw, setting);\n} catch (IllegalArgumentException e) {\n    // surface to the user/config layer with the setting name; do not silently default\n    throw new ConfigException(\"Invalid value for [\" + setting + \"]: \" + raw, e);\n}","preventionTips":["Always specify a unit suffix (s, ms, m, h, d) — never a bare negative number.","Treat -1 as the only legal negative; clamp computed durations to Math.max(-1, value).","Validate user/config time strings with a regex before forwarding to TimeValue.","In tests, assert that settings derived from formulas can never underflow below -1."],"tags":["time-value","settings","configuration","parse","elasticsearch-core"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}