{"record":{"id":"c90c5e4cc021c206","repo":"eclipse-vertx/vert.x","slug":"cannot-set-connecthandler-when-server-is-listening","errorCode":null,"errorMessage":"Cannot set connectHandler when server is listening","messagePattern":"Cannot set connectHandler 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":130,"sourceCode":"    this.fileRegionEnabled = fileRegionEnabled;\n    this.registerWriteHandler = registerWriteHandler;\n    this.sslOptions = sslOptions;\n    this.sslEngineOptions = sslEngineOptions;\n  }\n\n  public ServerSslContextProvider sslContextProvider() {\n    return sslContextProviderRef.get();\n  }\n\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  }","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/net/impl/tcp/NetServerImpl.java#L112-L148","documentation":"NetServerImpl guards its connect handler against changes once the server has started accepting connections. The handler is wired into the accept pipeline at bind time, so replacing it on a listening server would leave the socket pipeline inconsistent. Vert.x throws IllegalStateException immediately rather than silently ignoring the call.","triggerScenarios":"Calling netServer.connectHandler(handler) after listen() has been called and while isListening() is still true.","commonSituations":"Reusing a server instance to swap connection logic at runtime; shared utility code that configures a server without knowing its listen state; framework integrations that re-apply handler configuration on reload.","solutions":["Set the connect handler before calling listen()","Create a new NetServer instance with the desired handler and listen on the same address after closing the old one","Inside the handler, dispatch to a mutable delegate so runtime changes swap the delegate, not the handler"],"exampleFix":"// before\nserver.listen();\nserver.connectHandler(sock -> handle(sock)); // IllegalStateException\n// after\nNetServer server = vertx.createNetServer();\nserver.connectHandler(sock -> handle(sock));\nserver.listen(1234);","handlingStrategy":"validation","validationCode":"if (server instanceof NetServerImpl impl ? !impl.isListening() : !configured) {\n  server.connectHandler(handler);\n} else {\n  throw new IllegalStateException(\"Cannot reconfigure a listening server\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  server.connectHandler(handler);\n} catch (IllegalStateException e) {\n  // server already listening: recreate or use a delegate handler\n}","preventionTips":["Configure all handlers immediately after vertx.createNetServer(), before listen()","Use a delegate/mutable-handler pattern if runtime swapping is needed","Centralize server construction in one factory that enforces ordering"],"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"}