eclipse-vertx/vert.x · error · IllegalStateException

Set connect handler first

Error message

Set connect handler first

What it means

A NetServer requires a connect handler before it can accept connections; without one, accepted sockets would have nowhere to go. listen() checks this precondition and throws IllegalStateException. Set the handler as part of server construction before binding.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/net/impl/tcp/NetServerImpl.java:169

  public Future<Void> shutdown(Duration timeout) {
    ConnectionGroup group = channelGroup;
    if (group == null) {
      return vertx.getOrCreateContext().succeededFuture();
    }
    return group.shutdown(timeout);
  }

  @Override
  public Future<NetServer> listen(SocketAddress localAddress) {
    return listen(vertx.getOrCreateContext(), localAddress);
  }

  public Future<NetServer> listen(ContextInternal context, SocketAddress localAddress) {
    if (localAddress == null) {
      throw new NullPointerException("No null bind local address");
    }
    if (handler == null) {
      throw new IllegalStateException("Set connect handler first");
    }
    return bind(context, localAddress).map(this);
  }

  @Override
  public Future<NetServer> listen() {
    return listen(config.getPort(), config.getHost());
  }

  public boolean isClosed() {
    return !isListening();
  }

  private class NetSocketInitializer {

    private final ContextInternal context;
    private final Handler<NetSocket> connectionHandler;
    private final Handler<Throwable> exceptionHandler;

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Call server.connectHandler(handler) before listen()
  2. If the server is only used to probe a port, still provide a no-op handler, e.g. s -> {}
  3. Reorder initialization so handler wiring precedes the listen call

Example fix

// before
NetServer server = vertx.createNetServer();
server.listen(1234); // IllegalStateException
// after
NetServer server = vertx.createNetServer();
server.connectHandler(sock -> {});
server.listen(1234);
Defensive patterns

Strategy: validation

Validate before calling

if (handler == null) throw new IllegalStateException("connectHandler must be set before listen");
server.connectHandler(handler);
server.listen(port);

Try / catch

try {
  return server.listen(port);
} catch (IllegalStateException e) {
  throw new IllegalStateException("Server misconfigured: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling any listen() overload on a NetServer whose connectHandler was never set (or was set after a previous listen attempt reset state).

Common situations: Creating a server purely to check port availability without wiring a handler; calling listen before configuration completes due to reordered initialization; relying on a default handler that does not exist.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/c50d800412ddc797. Report an issue: GitHub.