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

  1. Start/register the backend TCP service so upstreams appear in admin and sync to the gateway
  2. Verify the service name and selector configuration in the shenyu-admin dashboard match what the TcpProxy request uses
  3. Check gateway data-sync connectivity (websocket/http) so upstream data is actually delivered
  4. 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

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


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)