alibaba/spring-ai-alibaba · error · RuntimeException
No available endpoint found for service: <serviceName>
Error message
No available endpoint found for service: <serviceName>
What it means
handleMcpStreamProtocol asks Nacos (nacosMcpOperationService.selectEndpoint) to resolve an MCP service reference to a live endpoint. When Nacos returns null — no healthy/registered instance matches the serviceRef — the callback throws a RuntimeException naming the service, since there is no address to build the SSE/streamable URL from.
Source
Thrown at spring-boot-starters/spring-ai-alibaba-starter-config-nacos/src/main/java/com/alibaba/cloud/ai/agent/nacos/tools/NacosMcpGatewayToolCallback.java:469
return "Error: Unsupported protocol " + protocol;
}
}
catch (Exception e) {
logger.error("[call] Unexpected error occurred", e);
return "Error: " + e.getMessage();
}
}
/**
* 处理MCP流式协议的工具调用 (mcp-sse, mcp-streamable)
*/
private String handleMcpStreamProtocol(Map<String, Object> args, McpServerRemoteServiceConfig remoteServerConfig,
String protocol) throws NacosException {
McpServiceRef serviceRef = remoteServerConfig.getServiceRef();
if (serviceRef != null) {
McpEndpointInfo mcpEndpointInfo = nacosMcpOperationService.selectEndpoint(serviceRef);
if (mcpEndpointInfo == null) {
throw new RuntimeException("No available endpoint found for service: " + serviceRef.getServiceName());
}
logger.info("[handleMcpStreamProtocol] Tool callback instance: {}", JacksonUtils.toJson(mcpEndpointInfo));
String exportPath = remoteServerConfig.getExportPath();
// 构建基础URL,根据协议类型调整
String transportProtocol = StringUtils.hasText(serviceRef.getTransportProtocol()) ? serviceRef.getTransportProtocol() : "http";
StringBuilder baseUrl;
if ("mcp-sse".equalsIgnoreCase(protocol)) {
baseUrl = new StringBuilder(transportProtocol + "://" + mcpEndpointInfo.getAddress() + ":" + mcpEndpointInfo.getPort());
}
else {
// mcp-streamable 或其他协议
baseUrl = new StringBuilder(transportProtocol + "://" + mcpEndpointInfo.getAddress() + ":" + mcpEndpointInfo.getPort());
}
logger.info("[handleMcpStreamProtocol] Processing {} protocol with args: {} and baseUrl: {}", protocol,
args, baseUrl.toString());View on GitHub (pinned to f82da0b50f)
Solutions
- Confirm the target MCP server is running and registered in Nacos under the exact serviceName in serviceRef (check Nacos console service list).
- Verify namespace, group and cluster names in McpServiceRef match those the MCP server registered with.
- Check instance health status in Nacos; restart or re-register unhealthy instances.
- Wrap the tool call with retry/fallback logic since endpoint availability can be transient.
Example fix
// before
McpServiceRef ref = McpServiceRef.builder().serviceName("my-mcp").build(); // wrong namespace
// after
McpServiceRef ref = McpServiceRef.builder().serviceName("my-mcp").namespace("public").groupName("DEFAULT_GROUP").build(); Defensive patterns
Strategy: retry
Validate before calling
McpEndpointInfo ep = nacosMcpOperationService.selectEndpoint(serviceRef);
if (ep == null) { throw new IllegalStateException("Precheck: MCP service not resolvable: " + serviceRef.getServiceName()); } Try / catch
try { return callback.call(args); }
catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("No available endpoint found")) {
return retry.withBackoff(3, call); // endpoint discovery is transient
}
throw e;
} Prevention
- Monitor the MCP service's healthy instance count in Nacos
- Keep namespace/group names consistent between gateway and MCP servers
- Add health checks so deregistered servers are caught before tool calls
When it happens
Trigger: call() -> handleMcpStreamProtocol with a valid serviceRef, but selectEndpoint(serviceRef) returns null: no instance registered under that service name, all instances unhealthy/disabled, or wrong namespace/group in the McpServiceRef.
Common situations: The MCP server backing the tool is not started or has been deregistered from Nacos; namespace/group mismatch between the gateway and the MCP server; the endpoint was published to a different Nacos cluster; network partition prevents endpoint discovery.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Please use getAgentCard(agentName) first.
- NacosRuntimeException(e.getErrCode(), e.getErrMsg())
- Register agent card to Nacos failed (rethrown as NacosRuntim
- Tool definition is null
- Protocol is null
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/619c26821719ea13.
Report an issue: GitHub.