aeron-io/aeron · error · InvalidChannelException

URI must have explicit control, endpoint, or be manual…

Error message

URI must have explicit control, endpoint, or be manual control-mode when original: channel=${originalUriString}

What it means

Aeron requires a UDP publication channel URI to be addressable: it must specify an explicit 'control' address, an 'endpoint' address, or declare 'control-mode=manual'. This InvalidChannelException is thrown during publication creation in the driver when the parsed UdpChannel satisfies none of these, because otherwise destinations could never be resolved.

Solutions

  1. Add endpoint=host:port to the channel URI for unicast publication
  2. Add control=host:port (typically with control-mode=dynamic) for MDC publication
  3. Add control-mode=manual for manual multi-destination control
  4. Fix the parameter spelling/URI construction so one of the three required options is present

Example fix

// before
Aeron.addPublication("aeron:udp?term-length=64k", 1001);
// after
Aeron.addPublication("aeron:udp?endpoint=localhost:40456|term-length=64k", 1001);
Defensive patterns

Strategy: validation

Validate before calling

UriPublication pub = UriPublication.parse(channel);
boolean valid = pub.hasControl() || pub.hasEndpoint() || "manual".equals(pub.get("control-mode"));
if (!valid) throw new IllegalArgumentException("publication URI needs endpoint, control, or control-mode=manual: " + channel);

Try / catch

try { aeron.addPublication(channel, streamId); } catch (InvalidChannelException e) { log.error("channel URI not addressable: {}", e.getMessage()); throw new ConfigException(channel); }

Prevention

When it happens

Trigger: Calling Aeron.addPublication/addExclusivePublication with a URI like "aeron:udp?term-length=64k" (no endpoint, no control, no manual control-mode), or an MDC publication where the original channel fails the re-validation (e.g. sparse/URI with session-id but no addressing params).

Common situations: Typo in parameter name (endpooint vs endpoint); assuming defaults provide an endpoint; building URIs programmatically and dropping the endpoint parameter; migrating a subscription-style URI to a publication.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at aeron-driver/src/main/java/io/aeron/driver/DriverConductor.java:1585

        return sendChannelEndpoint;
    }

    private SendChannelEndpoint findExistingSendChannelEndpoint(final UdpChannel udpChannel)
    {
        if (udpChannel.hasTag())
        {
            for (final SendChannelEndpoint endpoint : sendChannelEndpointByChannelMap.values())
            {
                if (endpoint.matchesTag(udpChannel))
                {
                    return endpoint;
                }
            }

            if (!udpChannel.hasExplicitControl() && !udpChannel.isManualControlMode() &&
                !udpChannel.channelUri().containsKey(ENDPOINT_PARAM_NAME))
            {
                throw new InvalidChannelException(
                    "URI must have explicit control, endpoint, or be manual control-mode when original: channel=" +
                        udpChannel.originalUriString());
            }
        }

        SendChannelEndpoint endpoint = sendChannelEndpointByChannelMap.get(udpChannel.canonicalForm());
        if (null != endpoint && endpoint.udpChannel().hasTag() && udpChannel.hasTag() &&
            endpoint.udpChannel().tag() != udpChannel.tag())
        {
            endpoint = null;
        }

        if (null != endpoint)
        {
            throwResourceTemporaryUnavailableIfEndpointIsClosing(endpoint);
        }

        return endpoint;

View on GitHub (pinned to 6d60124e15)