{"record":{"id":"e097bea749199055","repo":"eclipse-vertx/vert.x","slug":"cannot-set-exceptionhandler-when-server-is-listeni","errorCode":null,"errorMessage":"Cannot set exceptionHandler when server is listening","messagePattern":"Cannot set exceptionHandler when server is listening","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/net/impl/tcp/NetServerImpl.java","lineNumber":139,"sourceCode":"\n  @Override\n  public synchronized Handler<NetSocket> connectHandler() {\n    return handler;\n  }\n\n  @Override\n  public synchronized NetServerImpl connectHandler(Handler<NetSocket> handler) {\n    if (isListening()) {\n      throw new IllegalStateException(\"Cannot set connectHandler when server is listening\");\n    }\n    this.handler = handler;\n    return this;\n  }\n\n  @Override\n  public synchronized NetServerImpl exceptionHandler(Handler<Throwable> handler) {\n    if (isListening()) {\n      throw new IllegalStateException(\"Cannot set exceptionHandler when server is listening\");\n    }\n    this.exceptionHandler = handler;\n    return this;\n  }\n\n  public int actualPort() {\n    NetServerImpl server = actualServer;\n    return server != null ? server.actualPort : actualPort;\n  }\n\n  @Override\n  public Future<Void> shutdown(Duration timeout) {\n    ConnectionGroup group = channelGroup;\n    if (group == null) {\n      return vertx.getOrCreateContext().succeededFuture();\n    }\n    return group.shutdown(timeout);\n  }","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/net/impl/tcp/NetServerImpl.java#L121-L157","documentation":"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.","triggerScenarios":"Calling netServer.exceptionHandler(handler) after listen() has succeeded.","commonSituations":"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.","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"],"exampleFix":"// before\nserver.listen(1234);\nserver.exceptionHandler(err -> log(err)); // IllegalStateException\n// after\nserver.exceptionHandler(err -> log(err));\nserver.listen(1234);","handlingStrategy":"validation","validationCode":"if (!isListening(server)) {\n  server.exceptionHandler(handler);\n}","typeGuard":null,"tryCatchPattern":"try {\n  server.exceptionHandler(handler);\n} catch (IllegalStateException e) {\n  // fall back to per-socket exception handling in the connect handler\n}","preventionTips":["Set exceptionHandler in the same setup block as connectHandler, before listen()","Handle runtime socket errors via socket.exceptionHandler() inside the connect handler"],"tags":["vertx","net-server","illegal-state","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}