eclipse-vertx/vert.x · error · IllegalStateException

Please set handler before server is listening

Error message

Please set handler before server is listening

What it means

TcpHttpServer.requestHandler() throws IllegalStateException when the server is already listening. Request routing is captured when the server starts, so Vert.x forbids changing it after listen() to guarantee consistent handling of in-flight connections.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/tcp/TcpHttpServer.java:119

    }
    return s.updateTrafficShapingOptions(options);
  }

  @Override
  public synchronized int actualPort() {
    NetServer s = tcpServer;
    return s != null ? s.actualPort() : 0;
  }

  @Override
  public HttpServerMetrics<?, ?> getMetrics() {
    return httpMetrics;
  }

  @Override
  public synchronized HttpServer requestHandler(Handler<HttpServerRequest> handler) {
    if (isListening()) {
      throw new IllegalStateException("Please set handler before server is listening");
    }
    requestHandler = handler;
    return this;
  }

  @Override
  public synchronized HttpServer webSocketHandler(Handler<ServerWebSocket> handler) {
    if (isListening()) {
      throw new IllegalStateException("Please set handler before server is listening");
    }
    webSocketHandler = handler;
    return this;
  }

  @Override
  public HttpServer webSocketHandshakeHandler(Handler<ServerWebSocketHandshake> handler) {
    if (isListening()) {
      throw new IllegalStateException("Please set handler before server is listening");

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Set requestHandler() before calling listen()
  2. Reorder initialization so handler wiring precedes listen()
  3. For dynamic routing, register a stable dispatcher handler up front and route internally
  4. Check isListening() before setting the handler to fail fast with your own message

Example fix

// before
server.listen(port);
server.requestHandler(req -> { ... }); // throws
// after
server.requestHandler(req -> { ... });
server.listen(port);
Defensive patterns

Strategy: validation

Validate before calling

if (server.isListening()) { throw new IllegalStateException("Cannot change requestHandler after listen"); }
server.requestHandler(req -> { ... });

Try / catch

try { server.requestHandler(h); } catch (IllegalStateException e) { log.error("requestHandler must be set before listen()", e); }

Prevention

When it happens

Trigger: Calling requestHandler(Handler<HttpServerRequest>) on a TcpHttpServer whose isListening() is true (listen() called previously).

Common situations: Setting the request handler after server startup in dependency-injection wiring; hot-swapping routing logic at runtime without a restart; double-initialization where the handler is set both before and after listen().

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/2d9527f0cfff1f8e. Report an issue: GitHub.