aeron-io/aeron · error · ConfigurationException

Archive.Context.controlChannel must be UDP media: uri=

Error message

Archive.Context.controlChannel must be UDP media: uri=${controlChannel}

What it means

Archive.controlChannel must be an aeron:udp URI, but a URI starting with something else (e.g. aeron:ipc or a malformed string) was supplied. The archive control endpoint uses unicast/multicast UDP so remote clients can connect; conclude() rejects anything else.

Solutions

  1. Set controlChannel to a UDP URI, e.g. aeron:udp?endpoint=0.0.0.0:8010
  2. Use an IPC URI only for localControlChannel, not controlChannel
  3. Validate the URI string starts with 'aeron:udp' before calling ctx.controlChannel(...)

Example fix

// before
ctx.controlChannel("aeron:ipc")
// after
ctx.controlChannel("aeron:udp?endpoint=0.0.0.0:8010")
Defensive patterns

Strategy: validation

Validate before calling

if (!ctx.controlChannel().startsWith("aeron:udp")) {
    throw new IllegalArgumentException("controlChannel must be aeron:udp");
}

Prevention

When it happens

Trigger: Passing an IPC channel URI (aeron:ipc) to controlChannel; typo in the URI scheme such as 'aeron:udp endpoint=...' without the '?' or missing endpoint parameter so startsWith(CommonContext.UDP_CHANNEL) fails.

Common situations: Copy-pasting the localControlChannel (which must be IPC) into controlChannel; hand-editing channel URIs and breaking the prefix; environment-specific property files with malformed URIs.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/Archive.java:1225

            if (fileIoMaxLength < TERM_MIN_LENGTH || !BitUtil.isPowerOfTwo(fileIoMaxLength))
            {
                throw new ConfigurationException("invalid fileIoMaxLength=" + fileIoMaxLength);
            }

            io.aeron.driver.Configuration.validateMtuLength(controlMtuLength);
            checkTermLength(controlTermBufferLength);

            if (controlChannelEnabled)
            {
                if (null == controlChannel)
                {
                    throw new ConfigurationException("Archive.Context.controlChannel must be set");
                }

                if (!controlChannel.startsWith(CommonContext.UDP_CHANNEL))
                {
                    throw new ConfigurationException(
                        "Archive.Context.controlChannel must be UDP media: uri=" + controlChannel);
                }
            }

            if (!localControlChannel.startsWith(CommonContext.IPC_CHANNEL))
            {
                throw new ConfigurationException("local control channel must be IPC media: uri=" + localControlChannel);
            }

            if (null == replicationChannel)
            {
                throw new ConfigurationException("Archive.Context.replicationChannel must be set");
            }

            if (recordingEventsEnabled() && null == recordingEventsChannel())
            {
                throw new ConfigurationException(
                    "Archive.Context.recordingEventsChannel must be set if " +

View on GitHub (pinned to 6d60124e15)