apache/dubbo · error · IllegalArgumentException

Unknown unit ${chronoUnit}

Error message

Unknown unit ${chronoUnit}

What it means

Thrown by DurationStyle.TimeUnit.fromChronoUnit(chronoUnit) when the passed ChronoUnit is not one of the supported units: NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, DAYS. The method maps a java.time.temporal.ChronoUnit to Dubbo's internal TimeUnit enum; unsupported ChronoUnit values (WEEKS, MONTHS, YEARS, etc.) cause this exception.

Source

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

            public Duration parse(String value) {
                return Duration.of(Long.parseLong(value), this.chronoUnit);
            }

            public long longValue(Duration value) {
                return this.longValue.apply(value);
            }

            public static TimeUnit fromChronoUnit(ChronoUnit chronoUnit) {
                if (chronoUnit == null) {
                    return TimeUnit.MILLIS;
                }
                for (TimeUnit candidate : values()) {
                    if (candidate.chronoUnit == chronoUnit) {
                        return candidate;
                    }
                }
                throw new IllegalArgumentException("Unknown unit " + chronoUnit);
            }

            public static TimeUnit fromSuffix(String suffix) {
                for (TimeUnit candidate : values()) {
                    if (candidate.suffix.equalsIgnoreCase(suffix)) {
                        return candidate;
                    }
                }
                throw new IllegalArgumentException("Unknown unit '" + suffix + "'");
            }
        }
    }
}

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Use one of the supported ChronoUnit values: NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, or DAYS.
  2. If you need weeks or months, convert the duration to days yourself before passing it to the duration converter.
  3. Pass null for the unit to get the default (MILLIS).

Example fix

// before
Duration d = DurationStyle.SIMPLE.parse("7", ChronoUnit.WEEKS);

// after
Duration d = DurationStyle.SIMPLE.parse("7", ChronoUnit.DAYS);
Defensive patterns

Strategy: validation

Validate before calling

Set<ChronoUnit> supported = EnumSet.of(
    ChronoUnit.NANOS, ChronoUnit.MICROS, ChronoUnit.MILLIS,
    ChronoUnit.SECONDS, ChronoUnit.MINUTES, ChronoUnit.HOURS, ChronoUnit.DAYS);
if (!supported.contains(chronoUnit)) {
    // unsupported — pick a fallback or reject
}

Type guard

static boolean isSupportedChronoUnit(ChronoUnit u) {
    return u == ChronoUnit.NANOS || u == ChronoUnit.MICROS || u == ChronoUnit.MILLIS
        || u == ChronoUnit.SECONDS || u == ChronoUnit.MINUTES
        || u == ChronoUnit.HOURS || u == ChronoUnit.DAYS;
}

Try / catch

try {
    return TimeUnit.fromChronoUnit(chronoUnit);
} catch (IllegalArgumentException e) {
    return TimeUnit.MILLIS; // safe default
}

Prevention

When it happens

Trigger: Calling fromChronoUnit with ChronoUnit.WEEKS, ChronoUnit.MONTHS, ChronoUnit.YEARS, ChronoUnit.DECADES, ChronoUnit.CENTURIES, etc. Called internally by SIMPLE.parse when a default unit is supplied that is out of the supported set.

Common situations: A Dubbo API or extension that lets callers specify a default ChronoUnit for duration parsing, and the caller passes WEEKS or MONTHS. Rare in typical property configuration; more common in programmatic SPI usage.

Related errors


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