aeron-io/aeron · error · IllegalArgumentException

unsupported time unit

Error message

unsupported time unit: <timeUnit>

What it means

ClusterClock.map converts a java.util.concurrent.TimeUnit to its ClusterTimeUnit representation (used in cluster mark file headers); TimeUnit values with no ClusterTimeUnit equivalent (e.g. MILLISECONDS, SECONDS, DAYS) hit the default branch and IllegalArgumentException is thrown.

Solutions

  1. Use only TimeUnit.NANOSECONDS or TimeUnit.MICROSECONDS with ClusterClock.map
  2. Normalize other units to nanoseconds before mapping (e.g. timeUnit.toNanos())
  3. Guard with a check on the TimeUnit before calling map

Example fix

// before
ClusterTimeUnit ctu = ClusterClock.map(TimeUnit.MILLISECONDS);
// after
ClusterTimeUnit ctu = ClusterClock.map(
    timeUnit == TimeUnit.MICROSECONDS ? TimeUnit.MICROSECONDS : TimeUnit.NANOSECONDS);
Defensive patterns

Strategy: validation

Validate before calling

if (timeUnit != TimeUnit.NANOSECONDS && timeUnit != TimeUnit.MICROSECONDS) {
    throw new IllegalArgumentException("ClusterClock supports only NANOS/MICROS");
}

Try / catch

try {
    ClusterTimeUnit ctu = ClusterClock.map(timeUnit);
} catch (IllegalArgumentException ex) {
    // normalize to NANOSECONDS and retry
}

Prevention

When it happens

Trigger: Passing TimeUnit.MILLISECONDS (or SECONDS/DAYS/MICRO-second-units not in the supported set) into ClusterClock.map when configuring or inspecting cluster time units.

Common situations: Custom cluster clock configuration using an unsupported TimeUnit; generic time-unit plumbing that passes arbitrary units into Aeron cluster APIs.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/06c854ff29116cea. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/service/ClusterClock.java:109

     *
     * @param timeUnit to map to a corresponding {@link ClusterTimeUnit}.
     * @return a corresponding {@link ClusterTimeUnit}.
     */
    static ClusterTimeUnit map(final TimeUnit timeUnit)
    {
        switch (timeUnit)
        {
            case MILLISECONDS:
                return ClusterTimeUnit.MILLIS;

            case MICROSECONDS:
                return ClusterTimeUnit.MICROS;

            case NANOSECONDS:
                return ClusterTimeUnit.NANOS;

            default:
                throw new IllegalArgumentException("unsupported time unit: " + timeUnit);
        }
    }

    /**
     * Map {@link ClusterTimeUnit} to a corresponding {@link TimeUnit}.
     *
     * @param clusterTimeUnit to map to a corresponding {@link TimeUnit}.
     * @return a corresponding {@link TimeUnit}, if {@link ClusterTimeUnit#NULL_VAL} is passed then defaults
     * to {@link TimeUnit#MILLISECONDS}.
     */
    static TimeUnit map(final ClusterTimeUnit clusterTimeUnit)
    {
        switch (clusterTimeUnit)
        {
            case NULL_VAL:
            case MILLIS:
                return TimeUnit.MILLISECONDS;

View on GitHub (pinned to 6d60124e15)