{"record":{"id":"70539691ff217b66","repo":"quarkusio/quarkus","slug":"client-is-closed","errorCode":null,"errorMessage":"Client is closed","messagePattern":"Client is closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientImpl.java","lineNumber":274,"sourceCode":"    public ClientContext getClientContext() {\n        return clientContext;\n    }\n\n    @Override\n    public void close() {\n        if (isClosed)\n            return;\n        isClosed = true;\n        httpClient.close();\n        if (closeVertx) {\n            vertx.close();\n        }\n        log.debug(\"Client is closed\");\n    }\n\n    void abortIfClosed() {\n        if (isClosed)\n            throw new IllegalStateException(\"Client is closed\");\n    }\n\n    public String getUserAgent() {\n        return userAgent;\n    }\n\n    public String getTlsConfigName() {\n        return tlsConfigName;\n    }\n\n    @Override\n    public WebTarget target(String uri) {\n        // close is checked in the other target call\n        Objects.requireNonNull(uri);\n        return target(UriBuilder.fromUri(uri));\n    }\n\n    @Override","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientImpl.java#L256-L292","documentation":"A REST Client operation was invoked after Client.close(). ClientImpl.abortIfClosed() is called by target(), invocation(), getSslContext(), getHostnameVerifier(), getConfiguration() and property(); once isClosed is set, all of these throw IllegalStateException because the client's resources have been released.","triggerScenarios":"Calling client.target(...), client.property(...), client.getConfiguration() or creating an invocation after close() was called on that Client instance (directly, via try-with-resources, or via an injected @CleanupClosed client / RestClient proxy lifecycle end).","commonSituations":"Closing the client in a finally block then reusing the field later; caching a Client in a singleton and closing it at shutdown while requests still arrive; CDI-managed REST client proxies used after their scope ended; double-close then rebuild attempts.","solutions":["Create a new Client via ClientBuilder after close; closed clients cannot be reopened","Keep a single long-lived Client open for the application lifetime instead of closing per request","Guard shared client references: null out or replace the field upon close so no stale reference is used","Do not close injected MicroProfile REST Client proxies yourself; let the container manage their lifecycle"],"exampleFix":"// before\nClient client = ClientBuilder.newBuilder().build();\nclient.close();\nWebTarget t = client.target(\"https://api\"); // IllegalStateException: Client is closed\n\n// after\nClient client = ClientBuilder.newBuilder().build();\nWebTarget t = client.target(\"https://api\");\n// close only when truly done, and never reuse afterwards","handlingStrategy":"try-catch","validationCode":"// track close state yourself when sharing a Client\nif (clientField == null || clientClosed) {\n    clientField = ClientBuilder.newBuilder().build(); clientClosed = false;\n}\nclientField.target(url);","typeGuard":"boolean clientUsable(Client c) {\n    try { c.getConfiguration(); return true; }\n    catch (IllegalStateException e) { return false; }\n}","tryCatchPattern":"try {\n    return client.target(url).request().get();\n} catch (IllegalStateException e) {\n    if (e.getMessage().equals(\"Client is closed\")) {\n        client = ClientBuilder.newBuilder().build(); // rebuild\n        return client.target(url).request().get();\n    }\n    throw e;\n}","preventionTips":["Keep one long-lived Client per application; do not close it per request","Never reuse a Client after close(); drop the reference immediately","Let the container manage injected MicroProfile REST Client proxies — never call close() on them","Add a shutdown hook ordering check so the client isn't closed while requests are in flight"],"tags":["lifecycle","rest-client","closed-resource"],"backgroundTag":"client-already-closed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}