alibaba/nacos · error · IllegalArgumentException

Legacy A2A Endpoint address must not be empty

Error message

Legacy A2A Endpoint address must not be empty

What it means

Thrown (as NacosApiException INVALID_PARAM via invalidEndpoint wrapper) when toInstance detects a blank address on an AgentEndpoint in a legacy A2A batch. Each endpoint must have a non-blank address to compose a valid URI for the Naming instance. The original IllegalArgumentException is caught in register() and re-thrown with PARAMETER_VALIDATE_ERROR.

Source

Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/a2a/CanonicalA2aEndpointOperationService.java:229

        }
    }
    
    private String childClientId(String parentClientId, String namespaceId, String agentName,
        String version) {
        String identity = parentClientId + CHILD_ID_SEPARATOR + namespaceId + CHILD_ID_SEPARATOR
            + agentName + CHILD_ID_SEPARATOR + version;
        return CHILD_CLIENT_ID_PREFIX
            + UUID.nameUUIDFromBytes(identity.getBytes(StandardCharsets.UTF_8));
    }
    
    private Service composeService(String namespaceId, String agentName) {
        return Service.newService(namespaceId, Constants.Agent.AGENT_ENDPOINT_GROUP,
            RadServiceNameComposer.compose(agentName, A2A_PROTOCOL));
    }
    
    private Instance toInstance(AgentEndpoint source) {
        if (StringUtils.isBlank(source.getAddress())) {
            throw new IllegalArgumentException("Legacy A2A Endpoint address must not be empty");
        }
        Endpoint endpoint = new Endpoint();
        endpoint.setUri(composeUri(source));
        endpoint.setTransport(source.getTransport());
        return AgentRuntimeEndpointMapper.toLegacyA2aInstance(endpoint, source.getVersion(),
            source.getProtocolVersion(), source.getTenant());
    }
    
    private String composeUri(AgentEndpoint endpoint) {
        String protocol = StringUtils.isBlank(endpoint.getProtocol())
            ? AiConstants.A2a.A2A_ENDPOINT_DEFAULT_PROTOCOL : endpoint.getProtocol();
        if (AiConstants.A2a.A2A_ENDPOINT_DEFAULT_PROTOCOL.equalsIgnoreCase(protocol)
            && endpoint.isSupportTls()) {
            protocol = "https";
        }
        String address = endpoint.getAddress();
        String host = address != null && address.indexOf(':') >= 0 && !address.startsWith("[")
            ? '[' + address + ']' : address;

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Filter out or reject endpoints with blank addresses before calling register.
  2. Ensure every AgentEndpoint in the batch has setAddress() called with a non-blank host/IP.
  3. Validate the endpoint collection client-side: for each e, assert StringUtils.isNotBlank(e.getAddress()).

Example fix

// before
endpoints.add(new AgentEndpoint()); // address not set
endpointOpService.register(parentClientId, ns, agentName, endpoints);

// after
List<AgentEndpoint> valid = endpoints.stream()
    .filter(e -> StringUtils.isNotBlank(e.getAddress()))
    .toList();
if (valid.isEmpty()) {
    throw new IllegalArgumentException("No endpoints with valid address");
}
endpointOpService.register(parentClientId, ns, agentName, valid);
Defensive patterns

Strategy: validation

Validate before calling

// Filter out endpoints with blank addresses before registering
List<AgentEndpoint> valid = endpoints.stream()
    .filter(e -> e != null && StringUtils.isNotBlank(e.getAddress()))
    .toList();
if (valid.isEmpty()) {
    throw new IllegalArgumentException("No endpoints with valid address");
}
endpointOpService.register(parentClientId, ns, agentName, valid);

Type guard

public static boolean allEndpointsHaveAddress(Collection<AgentEndpoint> endpoints) {
    if (endpoints == null || endpoints.isEmpty()) {
        return false;
    }
    return endpoints.stream().allMatch(
        e -> e != null && StringUtils.isNotBlank(e.getAddress()));
}

Try / catch

try {
    endpointOpService.register(parentClientId, ns, agentName, endpoints);
} catch (NacosApiException e) {
    if (e.getDetailErrCode() == ErrorCode.PARAMETER_VALIDATE_ERROR.getCode()
            && e.getMessage().contains("address must not be empty")) {
        // filter and retry
        var valid = endpoints.stream()
            .filter(e -> StringUtils.isNotBlank(e.getAddress())).toList();
        endpointOpService.register(parentClientId, ns, agentName, valid);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling register with an AgentEndpoint whose getAddress() is null, empty, or whitespace-only. Endpoint list deserialized from JSON where the 'address' field was missing or empty. Endpoint object constructed without setting the address.

Common situations: Client-side bug where address is populated from a config that was not loaded. Endpoint auto-discovery producing entries with blank addresses for unhealthy instances. JSON schema drift where the address field was renamed but the deserializer still expects 'address'.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/7e5dd209347ad658. Report an issue: GitHub.