aeron-io/aeron · error · IllegalArgumentException

No port specified on resolvedEndpoint=

Error message

No port specified on resolvedEndpoint=<resolvedEndpoint>

What it means

ChannelUri.replaceEndpointWildcardPort() substitutes the wildcard endpoint of the channel with a concrete resolved endpoint. It requires the resolvedEndpoint string to contain a ':' separating host and port; if none is found it throws IllegalArgumentException.

Solutions

  1. Ensure the resolved endpoint string includes the port (host:port) before calling replaceEndpointWildcardPort
  2. Derive it from InetSocketAddress and use toString() so host and port are both present
  3. Guard before calling: check the string contains ':' and reject otherwise

Example fix

// before
publication.replaceEndpointWildcardPort(addr.getHostName()); // no port
// after
InetSocketAddress addr = ...;
publication.replaceEndpointWildcardPort(addr.getHostString() + ":" + addr.getPort());
Defensive patterns

Strategy: validation

Validate before calling

static void requireHostPort(String resolvedEndpoint) {
    if (resolvedEndpoint == null || resolvedEndpoint.lastIndexOf(':') < 0) {
        throw new IllegalArgumentException("resolvedEndpoint must be host:port, got: " + resolvedEndpoint);
    }
}

Type guard

static boolean hasPort(String endpoint) {
    int i = endpoint == null ? -1 : endpoint.lastIndexOf(':');
    return i > 0 && i < endpoint.length() - 1 && endpoint.substring(i + 1).chars().allMatch(Character::isDigit);
}

Try / catch

try {
    channelUri.replaceEndpointWildcardPort(resolvedEndpoint);
} catch (IllegalArgumentException e) {
    log.error("Bad resolved endpoint '{}'", resolvedEndpoint, e);
    throw new IllegalArgumentException("resolvedEndpoint must include a port", e);
}

Prevention

When it happens

Trigger: Calling replaceEndpointWildcardPort() with a resolvedEndpoint lacking a port, e.g. "192.168.1.10" or "myhost" instead of "192.168.1.10:40456". Observed in tests replay, shouldThrowIfResolvedEndpointInvalid, assertSubstitution, liveLogRecord.

Common situations: Resolution code that returns only the hostname (e.g. from DNS/InetAddress.getHostName()) without appending the port; log/recorded endpoints printed without port then fed back.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/ChannelUri.java:618

        return uri;
    }

    /**
     * Uses the supplied endpoint to resolve any wildcard ports. If the existing endpoint has a value of "0" for then
     * the port of this endpoint will be used instead. If the endpoint is not specified in this uri, then the whole
     * supplied endpoint is used. If the endpoint exists and has a non-wildcard port, then the existing endpoint is
     * retained.
     *
     * @param resolvedEndpoint The endpoint to supply a resolved endpoint port.
     * @throws IllegalArgumentException if the supplied resolvedEndpoint does not have a port or the port is zero.
     * @throws NullPointerException     if the supplied resolvedEndpoint is null
     */
    public void replaceEndpointWildcardPort(final String resolvedEndpoint)
    {
        final int portSeparatorIndex = requireNonNull(resolvedEndpoint, "resolvedEndpoint is null").lastIndexOf(':');
        if (-1 == portSeparatorIndex)
        {
            throw new IllegalArgumentException("No port specified on resolvedEndpoint=" + resolvedEndpoint);
        }
        if (resolvedEndpoint.endsWith(":0"))
        {
            throw new IllegalArgumentException("Wildcard port specified on resolvedEndpoint=" + resolvedEndpoint);
        }

        final String existingEndpoint = get(ENDPOINT_PARAM_NAME);
        if (null == existingEndpoint)
        {
            put(ENDPOINT_PARAM_NAME, resolvedEndpoint);
        }
        else if (existingEndpoint.endsWith(":0"))
        {
            final String endpoint = existingEndpoint.substring(0, existingEndpoint.length() - 2) +
                resolvedEndpoint.substring(resolvedEndpoint.lastIndexOf(':'));
            put(ENDPOINT_PARAM_NAME, endpoint);
        }
    }

View on GitHub (pinned to 6d60124e15)