apache/dubbo · error · IllegalArgumentException

'${value}' is not a valid duration

Error message

'${value}' is not a valid duration

What it means

Thrown by DurationStyle.detect(value) when the value matches NEITHER the SIMPLE pattern nor the ISO-8601 pattern. detect() iterates all DurationStyle enum values and throws if none matches. This means the string is structurally unrecognizable as any supported duration format.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/convert/StringToDurationConverter.java:152

        public static Duration detectAndParse(String value, ChronoUnit unit) {
            return detect(value).parse(value, unit);
        }

        /**
         * Detect the style from the given source value.
         *
         * @param value the source value
         * @return the duration style
         * @throws IllegalArgumentException if the value is not a known style
         */
        public static DurationStyle detect(String value) {
            Assert.notNull(value, "Value must not be null");
            for (DurationStyle candidate : values()) {
                if (candidate.matches(value)) {
                    return candidate;
                }
            }
            throw new IllegalArgumentException("'" + value + "' is not a valid duration");
        }

        /**
         * Time Unit that support.
         */
        enum TimeUnit {

            /**
             * Nanoseconds.
             */
            NANOS(ChronoUnit.NANOS, "ns", Duration::toNanos),

            /**
             * Microseconds.
             */
            MICROS(ChronoUnit.MICROS, "us", (duration) -> duration.toNanos() / 1000L),

            /**

View on GitHub (pinned to 3a3043227f)

Solutions

  1. If you need a fractional duration, convert it to an integer in a smaller unit (e.g. 1500ms instead of 1.5s).
  2. Ensure the value is either: an integer optionally followed by a supported suffix, or a valid ISO-8601 duration starting with P.
  3. Strip any non-essential whitespace or special characters from the value before passing it to the converter.

Example fix

// before
dubbo.consumer.timeout=1.5s

// after
dubbo.consumer.timeout=1500ms
Defensive patterns

Strategy: validation

Validate before calling

try {
    DurationStyle.detect(value);
} catch (IllegalArgumentException e) {
    // unrecognized format — handle before calling detectAndParse
}

Type guard

static boolean isRecognizableDuration(String v) {
    if (v == null) return false;
    return v.matches("[+-]?\\\\d+[a-zA-Z]{0,2}") || v.matches("[+-]?[pP].*");
}

Try / catch

try {
    return DurationStyle.detectAndParse(value);
} catch (IllegalArgumentException e) {
    return Duration.ofMillis(defaultMillis);
}

Prevention

When it happens

Trigger: Calling DurationStyle.detect(value) or detectAndParse(value) with a value that is not purely numeric-with-optional-suffix and does not start with P/p. Examples: empty-after-trim strings, "abc", "1.5s" (decimal not supported in SIMPLE), "1.5e3", "@500ms".

Common situations: Supplying a floating-point duration like 1.5s (Dubbo's SIMPLE pattern only accepts integers). Supplying a value with leading/trailing special characters. A null-guarded but whitespace-only value. Confusion with Spring Boot's relaxed duration format that allows decimals.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/815f1822aea661d7. Report an issue: GitHub.