apache/shenyu · error · ShenyuException

can not find port automatically !

Error message

can not find port automatically ! 

What it means

PortUtils.findPort tries several strategies to auto-detect the local HTTP port of the running client (Spring WebFlux/Netty via application env, external Tomcat via MBeans). If every strategy throws, it wraps the last failure in a ShenyuException because the client cannot register a valid URI without a port.

Solutions

  1. Set the port explicitly in client config (e.g. `server.port: 8189` and matching `shenyu.client...port`) so detection isn't needed.
  2. Ensure the app actually starts a web server (spring-boot-starter-web/webflux present) before registration runs.
  3. If using an external Tomcat, confirm exactly one Connector MBean is exposed (see error 109) — multiple instances also break detection.
  4. Register metadata manually or pin `shenyu.client.<framework>.props.port` in yml instead of auto-detection.

Example fix

# before (port auto-detect fails)
shenyu:
  client:
    http:
      props:
        contextPath: /demo
# after (explicit port)
server:
  port: 8189
shenyu:
  client:
    http:
      props:
        contextPath: /demo
        port: 8189
Defensive patterns

Strategy: try-catch

Validate before calling

boolean canDetectPort = env.containsProperty("local.server.port")
        || env.containsProperty("server.port")
        || isExternalTomcatPresent();

Try / catch

int port;
try {
    port = PortUtils.findPort();
} catch (ShenyuException e) {
    port = env.getProperty("server.port", Integer.class, 8189);
    LOGGER.warn("port auto-detect failed ({}), using configured port {}", e.getMessage(), port);
}

Prevention

When it happens

Trigger: Calling findPort when: the Spring environment has no `local.server.port`/`local.management.port` property, the app is not a web app (no WebServerApplicationContext), and no external Tomcat Connector MBean exists — all getPort strategies fail.

Common situations: Non-web Shenyu client starting without an embedded server; running in a container where the port property isn't propagated; using a server stack PortUtils doesn't recognize (e.g. Jetty/Undertow without Tomcat MBeans); unit tests without a real web server.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/dd7af9d770f508c5. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/utils/PortUtils.java:65

     * @throws ShenyuException when can not find port
     */
    @SuppressWarnings("all")
    public static int findPort(final BeanFactory beanFactory) {
        try {
            //works fine for springboot 2.x
            return getPort(beanFactory, "org.springframework.boot.web.server.AbstractConfigurableWebServerFactory");
        } catch (Exception ignored) {
        }
        try {
            //works fine for springboot 1.x
            return getPort(beanFactory, "org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer");
        } catch (Exception ignored) {
        }
        try {
            //works for springmvc with external tomcat
            return PortUtils.getPort();
        } catch (Exception e) {
            throw new ShenyuException("can not find port automatically ! ");
        }
    }

    /**
     * get container port.
     *
     * @param beanFactory beanFactory
     * @param className   className
     * @return container port
     */
    private static int getPort(final BeanFactory beanFactory, final String className) throws ClassNotFoundException,
            NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        final Class<?> clazz = Class.forName(className);
        final Method method = clazz.getMethod("getPort");
        final Object bean = beanFactory.getBean(clazz);
        return (int) method.invoke(bean);
    }

View on GitHub (pinned to 567142e072)