elastic/elasticsearch · error · IllegalArgumentException

failed to parse setting [{}] with value [{}] as a time value

Error message

failed to parse setting [{}] with value [{}] as a time value: unit is missing or unrecognized

What it means

Thrown by TimeValue.parseTimeValue when the input string has no recognized unit suffix or ends with an unknown suffix. Recognized suffixes are `ms`, `s`, `m`, `h`, `d` (and `micros`, `nanos` for the long overloads). A bare number like `5` or a value like `5x` falls through every suffix check, matches neither the `-0*1` (minus-one) nor `0+` (zero) patterns, and is rejected. The message includes the setting name and raw value for diagnosis.

Source

Thrown at libs/core/src/main/java/org/elasticsearch/core/TimeValue.java:404

            return new TimeValue(parse(sValue, normalized, "micros", settingName), TimeUnit.MICROSECONDS);
        } else if (normalized.endsWith("ms")) {
            return TimeValue.timeValueMillis(parse(sValue, normalized, "ms", settingName));
        } else if (normalized.endsWith("s")) {
            return TimeValue.timeValueSeconds(parse(sValue, normalized, "s", settingName));
        } else if (sValue.endsWith("m")) {
            // parsing minutes should be case-sensitive as 'M' means "months", not "minutes"; this is the only special case.
            return TimeValue.timeValueMinutes(parse(sValue, normalized, "m", settingName));
        } else if (normalized.endsWith("h")) {
            return TimeValue.timeValueHours(parse(sValue, normalized, "h", settingName));
        } else if (normalized.endsWith("d")) {
            return new TimeValue(parse(sValue, normalized, "d", settingName), TimeUnit.DAYS);
        } else if (normalized.matches("-0*1")) {
            return TimeValue.MINUS_ONE;
        } else if (normalized.matches("0+")) {
            return TimeValue.ZERO;
        } else {
            // Missing units:
            throw new IllegalArgumentException(
                "failed to parse setting [" + settingName + "] with value [" + sValue + "] as a time value: unit is missing or unrecognized"
            );
        }
    }

    private static long parse(final String initialInput, final String normalized, final String suffix, String settingName) {
        final String s = normalized.substring(0, normalized.length() - suffix.length()).trim();
        try {
            final long value = Long.parseLong(s);
            if (value < -1) {
                // -1 is magic, but reject any other negative values
                throw new IllegalArgumentException(
                    "failed to parse setting ["
                        + settingName
                        + "] with value ["
                        + initialInput
                        + "] as a time value: negative durations are not supported"
                );

View on GitHub (pinned to db6a809a66)

Solutions

  1. Append a recognized unit: `5s`, `500ms`, `10m`, `1h`, `7d`.
  2. Use `-1` for infinite/undefined where the setting allows it.
  3. Use `0` explicitly when you mean zero (do not rely on empty string).
  4. For minutes use lowercase `m`; uppercase `M` is reserved for months and will not parse as minutes.

Example fix

// before
PUT /my-index/_settings { "index.refresh_interval": "5" }
// after
PUT /my-index/_settings { "index.refresh_interval": "5s" }
Defensive patterns

Strategy: validation

Validate before calling

static final Pattern TIME = Pattern.compile("-?(?:0|[1-9][0-9]*)(?:ns|micros|ms|s|m|h|d)");
static boolean isParsableTimeValue(String v) {
    if (v == null) return false;
    if (v.matches("-0*1") || v.matches("0+")) return true;
    return TIME.matcher(v).matches();
}

Type guard

static boolean looksLikeTimeValue(String v) {
    if (v == null || v.isBlank()) return false;
    String n = v.trim().toLowerCase(Locale.ROOT);
    return n.matches("-?(?:0|[1-9][0-9]*)(ns|micros|ms|s|m|h|d)")
        || n.matches("-0*1") || n.matches("0+");
}

Try / catch

try {
    TimeValue tv = TimeValue.parseTimeValue(raw, null, settingName);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("unit is missing or unrecognized")) {
        // prompt user for the correct unit (s/ms/m/h/d) and retry
    } else throw e;
}

Prevention

When it happens

Trigger: Writing `refresh_interval: 5` (missing unit) in an index setting. Typing `5sec` instead of `5s`. Using uppercase `5S` (only lowercase is accepted for the case-insensitive suffixes, and `M` is case-sensitive to distinguish minutes from months). Mixing locale-specific decimal separators.

Common situations: Operators copy values from other systems (Prometheus `5s`, Java Duration `PT5S`) without translating. YAML auto-coercing `5` to an integer. Docs examples trimmed of the unit. Negative values other than `-1`.

Understand the failure class

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/292fec9c4dc6caf3. Report an issue: GitHub.