eclipse-vertx/vert.x · error · IllegalStateException
Cannot set exceptionHandler when server is listening
Error message
Cannot set exceptionHandler when server is listening
What it means
Like connectHandler, the server's exception handler is only applied while the server is being set up. Mutating it after the server started listening would not affect the already-built channel pipelines, so Vert.x throws IllegalStateException to surface the mistake. This keeps handler configuration strictly a pre-listen operation.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/net/impl/tcp/NetServerImpl.java:139
@Override
public synchronized Handler<NetSocket> connectHandler() {
return handler;
}
@Override
public synchronized NetServerImpl connectHandler(Handler<NetSocket> handler) {
if (isListening()) {
throw new IllegalStateException("Cannot set connectHandler when server is listening");
}
this.handler = handler;
return this;
}
@Override
public synchronized NetServerImpl exceptionHandler(Handler<Throwable> handler) {
if (isListening()) {
throw new IllegalStateException("Cannot set exceptionHandler when server is listening");
}
this.exceptionHandler = handler;
return this;
}
public int actualPort() {
NetServerImpl server = actualServer;
return server != null ? server.actualPort : actualPort;
}
@Override
public Future<Void> shutdown(Duration timeout) {
ConnectionGroup group = channelGroup;
if (group == null) {
return vertx.getOrCreateContext().succeededFuture();
}
return group.shutdown(timeout);
}View on GitHub (pinned to fb308bd8c3)
Solutions
- Set the exception handler before calling listen()
- Register per-socket exception handling via socket.exceptionHandler() inside the connect handler for runtime error handling
- Recreate and re-bind the server if the handler truly must change
Example fix
// before server.listen(1234); server.exceptionHandler(err -> log(err)); // IllegalStateException // after server.exceptionHandler(err -> log(err)); server.listen(1234);
Defensive patterns
Strategy: validation
Validate before calling
if (!isListening(server)) {
server.exceptionHandler(handler);
} Try / catch
try {
server.exceptionHandler(handler);
} catch (IllegalStateException e) {
// fall back to per-socket exception handling in the connect handler
} Prevention
- Set exceptionHandler in the same setup block as connectHandler, before listen()
- Handle runtime socket errors via socket.exceptionHandler() inside the connect handler
When it happens
Trigger: Calling netServer.exceptionHandler(handler) after listen() has succeeded.
Common situations: Attempting to install a global error logger after startup; config reload code re-registering handlers on a live server; copy-pasted setup blocks executed twice.
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
- Cannot set connectHandler when server is listening
- Set connect handler first
- Listen already called
- Parsing already done
- Already started
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/e097bea749199055.
Report an issue: GitHub.