apache/dubbo · error · IllegalArgumentException

'${value}' is not a valid ISO-8601 duration

Error message

'${value}' is not a valid ISO-8601 duration

What it means

Thrown by DurationStyle.ISO8601.parse() when a value matches the ISO-8601 pattern (^([+-]?[pP].*$)) but Duration.parse(value) fails — meaning the string starts with P/p (so it's routed here) but does not conform to the ISO-8601 duration grammar (e.g. Pxyz). Java's Duration.parse requires the standard form like PT1H30M, P1D, etc.

Source

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

                                    ? TimeUnit.fromSuffix(suffix)
                                    : TimeUnit.fromChronoUnit(unit))
                            .parse(matcher.group(1));
                } catch (Exception ex) {
                    throw new IllegalArgumentException("'" + value + "' is not a valid simple duration", ex);
                }
            }
        },

        /**
         * ISO-8601 formatting.
         */
        ISO8601("^[+-]?[pP].*$") {
            @Override
            public Duration parse(String value, ChronoUnit unit) {
                try {
                    return Duration.parse(value);
                } catch (Exception ex) {
                    throw new IllegalArgumentException("'" + value + "' is not a valid ISO-8601 duration", ex);
                }
            }
        };

        private final Pattern pattern;

        DurationStyle(String pattern) {
            this.pattern = Pattern.compile(pattern);
        }

        protected final boolean matches(String value) {
            return this.pattern.matcher(value).matches();
        }

        protected final Matcher matcher(String value) {
            return this.pattern.matcher(value);
        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Use a correct ISO-8601 duration: start with P, use T before time components (e.g. PT5M30S for 5 min 30 sec).
  2. If the value was not meant to be ISO-8601 but starts with P/p, switch to the simple format (e.g. 5m or 300s) so detect() routes it to SIMPLE.
  3. Check the chained cause (DateTimeParseException) for the exact parse position of the failure.

Example fix

// before
dubbo.provider.timeout=PT

// after
dubbo.provider.timeout=PT5S  // or simply: 5000 (ms)
Defensive patterns

Strategy: validation

Validate before calling

try {
    Duration.parse(value);
} catch (DateTimeParseException e) {
    // not valid ISO-8601 — log or fall back
}

Type guard

static boolean isValidIsoDuration(String v) {
    if (v == null || v.isEmpty()) return false;
    try { Duration.parse(v); return true; }
    catch (Exception e) { return false; }
}

Try / catch

try {
    return DurationStyle.ISO8601.parse(value, null);
} catch (IllegalArgumentException e) {
    return Duration.ofMillis(defaultMillis);
}

Prevention

When it happens

Trigger: Calling DurationStyle.detectAndParse(value) where value starts with P or p but is not a syntactically valid ISO-8601 duration. For example "P", "Px", "PT", or "P1" (missing time designator). Values like "PT0.5S" or "P1DT2H" are valid.

Common situations: Manually writing an ISO-8601 duration string with a typo. Confusing the date-period format with the duration format. A value that coincidentally starts with 'P' but was never intended to be ISO-8601 (e.g. a hostname or property name beginning with P).

Related errors


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