aeron-io/aeron · error · InvalidChannelException

endpoint has port=0 for send destination: channel=

Error message

endpoint has port=0 for send destination: channel={destinationUri}

What it means

A send destination URI includes an endpoint parameter ending in ":0", i.e. an explicitly requested port 0. Port 0 (ephemeral) is not meaningful for a send destination because the driver must send data to a concrete remote port; the driver throws InvalidChannelException.

Solutions

  1. Set a concrete remote port in the destination endpoint (e.g. endpoint=host:40456).
  2. If a dynamic local port is needed, use the interface/endpoints parameter for binding, not the send endpoint.
  3. Add pre-call validation: reject destination URIs whose endpoint ends with ":0".

Example fix

// before
publication.addDestination("aeron:udp?endpoint=host:0");
// after
publication.addDestination("aeron:udp?endpoint=host:40456");
Defensive patterns

Strategy: validation

Validate before calling

ChannelUri uri = ChannelUri.parse(destination);
String endpoint = uri.get("endpoint");
if (endpoint != null && endpoint.endsWith(":0")) throw new IllegalArgumentException("send destination endpoint needs a concrete port");

Type guard

boolean hasConcreteSendPort(ChannelUri uri) {
  String ep = uri.get("endpoint");
  return ep == null || !ep.endsWith(":0");
}

Try / catch

try { publication.addDestination(destination); }
catch (InvalidChannelException e) { if (e.getMessage().contains("has port=0 for send destination")) { /* set a real port */ } else throw e; }

Prevention

When it happens

Trigger: Calling Publication.addDestination() or creating an MDC send channel with a destination like "aeron:udp?endpoint=host:0".

Common situations: Unfilled port placeholders in generated configs; copying a bind-endpoint (where port 0 can request an ephemeral local port) into an endpoint used as a send target; typos like ":O" avoided but ":0" kept.

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

Appendix: source

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

                throw new InvalidChannelException(
                    "destinations must not contain the key: " + invalidKey + " channel=" + destinationUri);
            }
        }

        if (Objects.equals(CONTROL_MODE_RESPONSE, uri.get(MDC_CONTROL_MODE_PARAM_NAME)))
        {
            throw new InvalidChannelException("destinations may not specify " +
                MDC_CONTROL_MODE_PARAM_NAME + "=" + CONTROL_MODE_RESPONSE);
        }
    }

    private static void validateSendDestinationUri(final ChannelUri uri, final String destinationUri)
    {
        final String endpoint = uri.get(ENDPOINT_PARAM_NAME);

        if (null != endpoint && endpoint.endsWith(":0"))
        {
            throw new InvalidChannelException(ENDPOINT_PARAM_NAME + " has port=0 for send destination: channel=" +
                destinationUri);
        }
    }

    @SuppressWarnings({ "unused", "UnnecessaryReturnStatement" })
    private static void validateExperimentalFeatures(final boolean enableExperimentalFeatures, final UdpChannel channel)
    {
        if (enableExperimentalFeatures)
        {
            return;
        }

        /*
         * Put experimental feature validation here.
         */
    }

    static FeedbackDelayGenerator resolveDelayGenerator(

View on GitHub (pinned to 6d60124e15)