aeron-io/aeron · error · ClusterException

zero services are only supported when…

Error message

zero services are only supported when ConsensusModuleExtension is enabled

What it means

Running a cluster with zero services is only supported via ConsensusModuleExtension. conclude() throws if no extension is configured but serviceCount is 0, because a normal consensus module must host at least one ClusteredService.

Solutions

  1. Register at least one ClusteredService or set context.serviceCount(n) with n >= 1 plus service container configurations.
  2. If you truly want zero services, enable the ConsensusModuleExtension via its configuration property.
  3. Verify how serviceCount is derived from the service container contexts you pass to ClusteredMediaDriver.launch().

Example fix

// before
ClusteredMediaDriver.launch(driverCtx, mediaCtx, moduleCtx); // serviceCount=0, no extension
// after
moduleCtx.serviceContainerContexts(List.of(new ClusteredServiceContainer.Context().clusteredService(new MyService())));
ClusteredMediaDriver.launch(driverCtx, mediaCtx, moduleCtx);
Defensive patterns

Strategy: validation

Validate before calling

if (null == Configuration.newConsensusModuleExtension() && ctx.serviceCount() == 0) {
    throw new IllegalArgumentException("register at least one clustered service or enable the extension");
}

Prevention

When it happens

Trigger: Launching ConsensusModule/ClusteredMediaDriver without registering any services (serviceCount == 0) and without the extension property set.

Common situations: Boilerplate copied from a driver-only test; forgetting to pass ClusteredServiceContainer contexts/serviceCount; intending to run extension mode but forgetting to set the extension property.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

            {
                egressPublisher = new EgressPublisher(leaderHeartbeatTimeoutNs);
            }

            final ChannelUri channelUri = parse(logChannel());
            isLogMdc = channelUri.isUdp() && null == channelUri.get(ENDPOINT_PARAM_NAME);

            if (null == consensusModuleExtension)
            {
                consensusModuleExtension = Configuration.newConsensusModuleExtension();
            }

            if (null != consensusModuleExtension && 0 != serviceCount)
            {
                throw new ClusterException("service count must be zero when ConsensusModuleExtension is enabled");
            }
            else if (null == consensusModuleExtension && 0 == serviceCount)
            {
                throw new ClusterException("zero services are only supported when ConsensusModuleExtension is enabled");
            }

            concludeMarkFile();

            if (CommonContext.shouldPrintConfigurationOnStart())
            {
                System.out.println(this);
            }
        }

        /**
         * Has the context had the {@link #conclude()} method called.
         *
         * @return true of the {@link #conclude()} method has been called.
         */
        public boolean isConcluded()
        {
            return isConcluded;

View on GitHub (pinned to 6d60124e15)