alibaba/nacos · critical · NacosRuntimeException
CLIENT_DISCONNECT
CLIENT_DISCONNECT
Error message
AI client connection already disconnected: ${parentClientId} What it means
Thrown by CanonicalA2aEndpointOperationService.ensureChildClient when the parent AI gRPC client connection (parentClientId) is no longer present in clientManager at the start of child-client creation. This is a NacosRuntimeException with CLIENT_DISCONNECT code, indicating the originating connection dropped before or during endpoint registration.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/a2a/CanonicalA2aEndpointOperationService.java:178
@Override
public void clientDisConnected(Connection connect) {
if (!RemoteConstants.LABEL_MODULE_AI
.equals(connect.getMetaInfo().getLabel(RemoteConstants.LABEL_MODULE))) {
return;
}
Set<String> children = childClientIds.remove(connect.getMetaInfo().getConnectionId());
if (children == null) {
return;
}
for (String childClientId : children) {
clientManager.clientDisconnected(childClientId);
}
}
private String ensureChildClient(String parentClientId, String namespaceId, String agentName,
String version) {
if (!clientManager.contains(parentClientId)) {
throw new NacosRuntimeException(NacosException.CLIENT_DISCONNECT,
"AI client connection already disconnected: " + parentClientId);
}
String childClientId = childClientId(parentClientId, namespaceId, agentName, version);
if (!clientManager.contains(childClientId)) {
ClientAttributes attributes = new ClientAttributes();
attributes.addClientAttribute(ClientConstants.CONNECTION_TYPE,
ClientConstants.DEFAULT_FACTORY);
clientManager.clientConnected(childClientId, attributes);
}
childClientIds.computeIfAbsent(parentClientId,
key -> ConcurrentHashMap.newKeySet()).add(childClientId);
if (!clientManager.contains(parentClientId)) {
disconnectChild(parentClientId, childClientId);
throw new NacosRuntimeException(NacosException.CLIENT_DISCONNECT,
"AI client connection already disconnected: " + parentClientId);
}
return childClientId;
}View on GitHub (pinned to 9b989acdf1)
Solutions
- Reconnect the AI gRPC client and obtain the new parentClientId before retrying endpoint registration.
- Verify clientManager.contains(parentClientId) is true before calling register.
- If the connection is flaky, add retry logic that re-establishes the connection on CLIENT_DISCONNECT.
- Check server logs for connection eviction reasons (idle timeout, resource pressure).
Example fix
// before
endpointOpService.register(staleParentClientId, ns, agentName, endpoints);
// after
if (!clientManager.contains(parentClientId)) {
parentClientId = reconnectAiClient(); // establish new gRPC connection
}
endpointOpService.register(parentClientId, ns, agentName, endpoints); Defensive patterns
Strategy: validation
Validate before calling
// Verify parent connection is alive before registering
if (!clientManager.contains(parentClientId)) {
parentClientId = reconnectAiGrpcClient(); // establish new connection
}
endpointOpService.register(parentClientId, ns, agentName, endpoints); Type guard
public static boolean isParentConnected(ClientManager mgr, String parentClientId) {
return mgr.contains(parentClientId);
} Try / catch
try {
endpointOpService.register(parentClientId, ns, agentName, endpoints);
} catch (NacosRuntimeException e) {
if (e.getCode() == NacosException.CLIENT_DISCONNECT) {
parentClientId = reconnectAiGrpcClient();
endpointOpService.register(parentClientId, ns, agentName, endpoints);
} else {
throw e;
}
} Prevention
- Always validate the gRPC connection is alive before endpoint operations.
- Implement reconnection logic that refreshes parentClientId on disconnect.
- Monitor gRPC connection health and keepalive timeouts.
When it happens
Trigger: The AI agent's gRPC connection disconnected (network failure, client shutdown, server-side eviction) before the register call reached ensureChildClient. A deregister or reconnect happened concurrently, removing the parent client from the manager. Stale parentClientId reused after reconnect produced a new connection ID.
Common situations: Network instability causing the gRPC connection to drop mid-operation. Client restart that created a new connection ID while old code path still references the old one. Long-running registration that outlived a connection keepalive timeout. Server-side connection eviction under memory pressure.
Related errors
- PARAMETER_MISSING
- MCP_SERVER_NOT_FOUND
- MCP_SERVER_REF_ENDPOINT_SERVICE_NOT_FOUND
- PARAMETER_VALIDATE_ERROR
- INVALID_PARAM
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/c7042d3b2fa155d6.
Report an issue: GitHub.