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
- Set requestHandler() before calling listen()
- Reorder initialization so handler wiring precedes listen()
- For dynamic routing, register a stable dispatcher handler up front and route internally
- 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
- Always set requestHandler before listen()
- Use a single setup method that configures handlers then listens
- For dynamic routing, use a stable dispatcher installed pre-listen
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
- Request has already been read
- Response has already been written
- Not listening
- 421 Misdirected Request
- size must be > 0
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/2d9527f0cfff1f8e.
Report an issue: GitHub.