{"record":{"id":"658f5690d27d30e7","repo":"eclipse-vertx/vert.x","slug":"client-is-closed","errorCode":null,"errorMessage":"Client is closed","messagePattern":"Client is closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientBase.java","lineNumber":134,"sourceCode":"    options = options.copy();\n    setDefaultSslOptions(options);\n    return Future.succeededFuture(true);\n  }\n\n  protected abstract void setDefaultSslOptions(ClientSSLOptions options);\n\n  public HttpClientBase proxyFilter(Predicate<SocketAddress> filter) {\n    proxyFilter = filter;\n    return this;\n  }\n\n  public VertxInternal vertx() {\n    return vertx;\n  }\n\n  protected void checkClosed() {\n    if (closeSequence.started()) {\n      throw new IllegalStateException(\"Client is closed\");\n    }\n  }\n}\n","sourceCodeStart":116,"sourceCodeEnd":138,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientBase.java#L116-L138","documentation":"HttpClientBase.checkClosed throws IllegalStateException when the client's close sequence has already started and an operation (request creation, connect, websocket, etc.) is attempted on the closed client. Vert.x clients are not reusable after close.","triggerScenarios":"Calling client.request(...) / websocket(...) / any operation after client.close() (or after the closeFuture completed); keeping a cached client instance used by a shutdown handler; closing the client in one callback while another request is still being initiated.","commonSituations":"Application shutdown racing with in-flight request creation; singleton client closed in a @PreDestroy/stop hook while a scheduler still fires requests; reusing a client obtained from a builder whose close future was resolved.","solutions":["Create a new HttpClient instance instead of using the closed one.","Check client's closeFuture.isComplete() (or guard with isClosed state) before issuing requests.","Ensure lifecycle ordering: stop schedulers/consumers before closing the client.","Catch IllegalStateException and lazily recreate the client if closed."],"exampleFix":"// before\nclient.close();\nclient.request(requestOptions); // IllegalStateException\n// after\nclient.close();\nHttpClient client = vertx.createHttpClient(options);\nclient.request(requestOptions);","handlingStrategy":"try-catch","validationCode":"if (client.closeFuture().isComplete()) {\n  client = vertx.createHttpClient(options);\n}","typeGuard":null,"tryCatchPattern":"try {\n  request = client.request(opts);\n} catch (IllegalStateException e) {\n  client = vertx.createHttpClient(options);\n  request = client.request(opts);\n}","preventionTips":["Own the client lifecycle in one place; stop producers before close().","Wrap the client in a supplier/holder that recreates it when closed.","Don't cache HttpClient instances beyond their owner's lifecycle."],"tags":["http-client","lifecycle","closed-resource"],"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"}