aeron-io/aeron · error · ClusterException

local archive control must be IPC

Error message

local archive control must be IPC

What it means

The ConsensusModule lives in the same process as the local archive, so its archive control request channel must be the IPC channel (aeron:ipc) rather than a network channel. conclude() validates archiveContext.controlRequestChannel() and throws if it does not start with the IPCChannel prefix.

Solutions

  1. Set the archive context control request channel to CommonContext.IPC_CHANNEL ("aeron:ipc").
  2. If you rely on defaults, do not override archiveContext.controlRequestChannel() with a udp URI.
  3. Check system properties (aeron.archive.control.channel etc.) that Archive.Context may pick up and override them for the cluster process.

Example fix

// before
archiveCtx.controlRequestChannel("aeron:udp?endpoint=localhost:8010");
// after
archiveCtx.controlRequestChannel(CommonContext.IPC_CHANNEL); // "aeron:ipc"
Defensive patterns

Strategy: validation

Validate before calling

if (!archiveCtx.controlRequestChannel().startsWith(CommonContext.IPC_CHANNEL)) {
    throw new IllegalArgumentException("archive controlRequestChannel must be " + CommonContext.IPC_CHANNEL);
}

Prevention

When it happens

Trigger: Configuring ConsensusModule.Context.archiveContext() with an Archive.Context whose controlRequestChannel() is a network channel like 'aeron:udp?endpoint=localhost:8010'.

Common situations: Copying an archive configuration from a remote-archive client setup; setting archive control channels via properties or system properties meant for a standalone archive; misreading docs that the cluster's local archive must be accessed over IPC.

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/ee28e9a4354c1097. Report an issue: GitHub.

Appendix: source

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

            if (null == timerServiceSupplier)
            {
                timerServiceSupplier = getTimerServiceSupplierFromSystemProperty();
            }

            if (null == archiveContext)
            {
                archiveContext = new AeronArchive.Context()
                    .controlRequestChannel(AeronArchive.Configuration.localControlChannel())
                    .controlResponseChannel(AeronArchive.Configuration.localControlChannel())
                    .controlRequestStreamId(AeronArchive.Configuration.localControlStreamId())
                    .controlResponseStreamId(
                        clusterId * 100 + 100 + AeronArchive.Configuration.controlResponseStreamId());
            }

            if (!archiveContext.controlRequestChannel().startsWith(CommonContext.IPC_CHANNEL))
            {
                throw new ClusterException("local archive control must be IPC");
            }

            if (!archiveContext.controlResponseChannel().startsWith(CommonContext.IPC_CHANNEL))
            {
                throw new ClusterException("local archive control must be IPC");
            }

            if (null == replicationChannel)
            {
                throw new ClusterException("replicationChannel must be set");
            }

            archiveContext
                .aeron(aeron)
                .errorHandler(null) // ensure that exceptions are re-thrown
                .ownsAeronClient(false)
                .lock(NoOpLock.INSTANCE)
                .controlRequestChannel(addAliasIfAbsent(

View on GitHub (pinned to 6d60124e15)