aeron-io/aeron · error · ClusterException

invalid TimerServiceSupplier

Error message

invalid TimerServiceSupplier: <timeServiceClassName>

What it means

ConsensusModule.Configuration.newTimerServiceSupplier() instantiates a TimerServiceSupplier by class name, accepting only known implementations (e.g. PriorityHeapTimerServiceSupplier). An unrecognized class name is rejected with ClusterException "invalid TimerServiceSupplier".

Solutions

  1. Use the built-in name PriorityHeapTimerServiceSupplier.class.getName().
  2. Correct the typo in the configured class name.
  3. Remove the property to use the default timer service supplier.
  4. If a custom supplier is required, construct it programmatically instead of by class name, or upgrade to a version supporting it.

Example fix

// before
System.setProperty("aeron.cluster.timer.service.supplier", "com.acme.MyTimerSupplier");
// after
System.setProperty("aeron.cluster.timer.service.supplier",
    "io.aeron.cluster.service.PriorityHeapTimerServiceSupplier");
Defensive patterns

Strategy: validation

Validate before calling

String name = System.getProperty("aeron.cluster.timer.service.supplier", "");
if (!name.isEmpty() && !"io.aeron.cluster.service.PriorityHeapTimerServiceSupplier".equals(name)) {
    throw new IllegalArgumentException("unsupported timer service supplier: " + name);
}

Try / catch

try { ConsensusModule.launch(ctx); } catch (ClusterException e) { if (e.getMessage().startsWith("invalid TimerServiceSupplier")) { log.error("check aeron.cluster.timer.service.supplier value"); } throw e; }

Prevention

When it happens

Trigger: Setting the timer service supplier property (aeron.cluster.timer.service.supplier) to a class name that is not one of the built-in suppliers and either is not on the classpath or is not a supported name.

Common situations: Typo in the fully-qualified class name; custom TimerServiceSupplier supplied by name without the module supporting arbitrary names; property copied from an incompatible Aeron version.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java:4606

        private TimerServiceSupplier getTimerServiceSupplierFromSystemProperty()
        {
            final String timeServiceClassName = Configuration.timerServiceSupplier();
            if (WheelTimerServiceSupplier.class.getName().equals(timeServiceClassName))
            {
                return new WheelTimerServiceSupplier(
                    clusterClock.timeUnit(),
                    0,
                    findNextPositivePowerOfTwo(
                        clusterClock.timeUnit().convert(wheelTickResolutionNs, TimeUnit.NANOSECONDS)),
                    ticksPerWheel);
            }
            else if (PriorityHeapTimerServiceSupplier.class.getName().equals(timeServiceClassName))
            {
                return new PriorityHeapTimerServiceSupplier();
            }

            throw new ClusterException("invalid TimerServiceSupplier: " + timeServiceClassName);
        }

        private void validateLogChannel()
        {
            final ChannelUri logChannelUri = parse(logChannel);
            if (logChannelUri.containsKey(INITIAL_TERM_ID_PARAM_NAME))
            {
                throw new ConfigurationException("logChannel must not contain: " + INITIAL_TERM_ID_PARAM_NAME);
            }
            if (logChannelUri.containsKey(TERM_ID_PARAM_NAME))
            {
                throw new ConfigurationException("logChannel must not contain: " + TERM_ID_PARAM_NAME);
            }
            if (logChannelUri.containsKey(TERM_OFFSET_PARAM_NAME))
            {
                throw new ConfigurationException("logChannel must not contain: " + TERM_OFFSET_PARAM_NAME);
            }
        }

View on GitHub (pinned to 6d60124e15)