apache/incubator-seata · critical · RuntimeException

Server start failed, the listen port: %s

Error message

Server start failed, the listen port: %s

What it means

Thrown by NettyServerBootstrap when the Seata Server's Netty listener fails to bind its service port and the underlying cause is a java.net.SocketException. The listen port is included in the message so you can identify which endpoint failed. The original SocketException is chained as the cause. This is a fatal startup error: the server cannot accept transaction coordination traffic until the port is free.

Source

Thrown at core/src/main/java/org/apache/seata/core/rpc/netty/NettyServerBootstrap.java:207

                                    new HttpDetector()
                                }));
                    }
                });

        try {
            this.serverBootstrap.bind(port).sync();
            LOGGER.info("Server started, service listen port: {}", getListenPort());
            Instance instance = Instance.getInstance();
            // Lines 177-180 are just for compatibility with test cases
            if (instance.getTransaction() == null) {
                Instance.getInstance().setTransaction(new Node.Endpoint(XID.getIpAddress(), XID.getPort(), "netty"));
            }
            for (RegistryService<?> registryService : MultiRegistryFactory.getInstances()) {
                registryService.register(Instance.getInstance());
            }
            initialized.set(true);
        } catch (SocketException se) {
            throw new RuntimeException("Server start failed, the listen port: " + getListenPort(), se);
        } catch (Exception exx) {
            throw new RuntimeException("Server start failed", exx);
        }
    }

    @Override
    public void shutdown() {
        try {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Shutting server down, the listen port: {}", getListenPort());
            }
            if (initialized.get()) {
                for (RegistryService registryService : MultiRegistryFactory.getInstances()) {
                    registryService.unregister(Instance.getInstance());
                    registryService.close();
                }
                // wait a few seconds for server transport
                TimeUnit.SECONDS.sleep(nettyServerConfig.getServerShutdownWaitTime());

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Find and stop the process occupying the port: `netstat -tlnp | grep <port>` or `lsof -i :<port>`, then kill it or wait for TIME_WAIT to clear.
  2. If a second server is intentional, change the listen port (e.g. server.servicePort / store config 8091 -> 8092) for one instance.
  3. If binding a privileged port (<1024) without root, switch to an unprivileged port or grant the JVM the needed capability.
  4. Inspect the chained cause (RuntimeException.getCause()) to confirm it is 'Address already in use' versus a permission-denied SocketException, and fix accordingly.

Example fix

// before: two instances both on 8091
# instance A
sh seata-server.sh -p 8091
# instance B on same host
sh seata-server.sh -p 8091   # -> Server start failed, the listen port: 8091

// after
# instance B
sh seata-server.sh -p 8092
Defensive patterns

Strategy: validation

Validate before calling

// before starting Seata server in-process / embedding it
try (java.net.ServerSocket probe = new java.net.ServerSocket(port)) {
    // port is free
} catch (java.net.BindException e) {
    throw new IllegalStateException("Port " + port + " already in use - pick another or stop the occupant", e);
}

Try / catch

try {
    nettyServerBootstrap.start();
} catch (RuntimeException e) {
    if (e.getCause() instanceof java.net.SocketException) {
        // port-level failure: report port, check occupancy, choose new port and retry once
    }
    throw e;
}

Prevention

When it happens

Trigger: serverBootstrap.bind(port).sync() throws SocketException: the configured service listen port (e.g. 8091, from service.port / netty port config) is already in use by another process, or the OS refused the bind (insufficient permissions for a privileged port, address already in use after an unclean shutdown, or the port is taken by another Seata instance).

Common situations: Running two Seata Server instances (or a leftover process from a previous run) on the same port; a previous server process still holding the port in TIME_WAIT; running in a container where the port was mapped/occupied; CI environments starting the server twice in parallel.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/2c8b14d4c2ea9dfa. Report an issue: GitHub.