apache/shenyu · error · ShenyuException
shenyu TcpProxy don't have any upstream
Error message
shenyu TcpProxy don't have any upstream
What it means
DefaultConnectionConfigProvider.getProxiedService builds the upstream list from the discovered DivideUpstream entries for a TCP proxy service; if the list is empty it means no healthy upstream instances exist for the requested backend, so selecting a target via the load balancer is impossible and a ShenyuException is thrown.
Solutions
- Start/register the backend TCP service so upstreams appear in admin and sync to the gateway
- Verify the service name and selector configuration in the shenyu-admin dashboard match what the TcpProxy request uses
- Check gateway data-sync connectivity (websocket/http) so upstream data is actually delivered
- Confirm backend instance health-check status; re-add healthy instances
Example fix
// before curl-like tcp request to a service with zero registered upstreams // after register the backend and confirm instances are visible in shenyu-admin before proxying
Defensive patterns
Strategy: validation
Validate before calling
List<DivideUpstream> upstreams = ...; if (upstreams == null || upstreams.isEmpty()) { failFast("no upstream registered for tcp service"); } Try / catch
try { service = provider.getProxiedService(...); } catch (ShenyuException e) { log.warn("no tcp upstream: {}", e.getMessage()); return fallbackResponse(); } Prevention
- Confirm the backend registers before the gateway proxies traffic
- Monitor upstream list size for the selector and alert on zero
- Verify data-sync channel health so upstream data reaches the gateway
When it happens
Trigger: Calling getProxiedService (via TcpProxy connection setup) when no upstream was registered for the service name, all upstreams were pruned as unhealthy/removed, or data-sync has not yet delivered the selector/upstream data to the gateway.
Common situations: Backend TCP service not started or not registered with admin; wrong service/selector name in the TCP request; gateway started before admin finished publishing config; all backend instances down so health checks removed them.
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
- Gateway address not found from registry.
- illegal param, serverLists configuration required if…
- Invalid upstream URL, expected 'host:port' format but was:
- please config the registerType and serverList
- response modify failure.
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/96165eca488f80a7.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-protocol/shenyu-protocol-tcp/src/main/java/org/apache/shenyu/protocol/tcp/connection/DefaultConnectionConfigProvider.java:64
private final String pluginSelectorName;
public DefaultConnectionConfigProvider(final String loadBalanceAlgorithm, final String pluginSelectorName) {
this.loadBalanceAlgorithm = loadBalanceAlgorithm;
this.pluginSelectorName = pluginSelectorName;
}
@Override
public URI getProxiedService(final String ip) {
List<Upstream> upstreamList = UpstreamProvider.getSingleton().provide(this.pluginSelectorName).stream().map(dp -> Upstream.builder()
.url(dp.getUrl())
.status(open(dp.getStatus()))
.weight(dp.getWeight())
.protocol(dp.getProtocol())
.warmup(JsonUtils.jsonToMap(dp.getProps(), Integer.class).get("warmupTime"))
.timestamp(dp.getDateCreated().getTime())
.build()).collect(Collectors.toList());
if (CollectionUtils.isEmpty(upstreamList)) {
throw new ShenyuException("shenyu TcpProxy don't have any upstream");
}
LoadBalanceData data = new LoadBalanceData();
data.setIp(ip);
Upstream upstream = LoadBalancerFactory.selector(upstreamList, loadBalanceAlgorithm, data);
return cover(upstream);
}
private URI cover(final Upstream upstream) {
try {
return new URI(upstream.getProtocol() + "://" + upstream.getUrl());
} catch (URISyntaxException e) {
LOG.error("Upstream url is wrong", e);
throw new ShenyuException(e);
}
}
/**
* false close, true open.View on GitHub (pinned to 567142e072)