{"record":{"id":"59756f55b2d62974","repo":"quarkusio/quarkus","slug":"stream-is-closed-59756f","errorCode":null,"errorMessage":"Stream is closed","messagePattern":"Stream is closed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/VertxClientInputStream.java","lineNumber":49,"sourceCode":"    @Override\n    public int read() throws IOException {\n        byte[] b = new byte[1];\n        int read = read(b);\n        if (read == -1) {\n            return -1;\n        }\n        return b[0] & 0xff;\n    }\n\n    @Override\n    public int read(final byte[] b) throws IOException {\n        return read(b, 0, b.length);\n    }\n\n    @Override\n    public int read(final byte[] b, final int off, final int len) throws IOException {\n        if (closed) {\n            throw new IOException(\"Stream is closed\");\n        }\n        readIntoBuffer();\n        if (finished) {\n            return -1;\n        }\n        if (len == 0) {\n            return 0;\n        }\n        ByteBuf buffer = pooled;\n        int copied = Math.min(len, buffer.readableBytes());\n        buffer.readBytes(b, off, copied);\n        if (!buffer.isReadable()) {\n            pooled.release();\n            pooled = null;\n        }\n        return copied;\n    }\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/VertxClientInputStream.java#L31-L67","documentation":"VertxClientInputStream.read throws IOException(\"Stream is closed\") when the response body stream has already been closed and read() is called again. This is standard InputStream closed-stream semantics: once the client response (and its underlying Netty connection buffer) is released, further reads are illegal.","triggerScenarios":"Calling read() on the Response.readEntity() stream after the response was closed, after the connection was returned to the pool, double-consuming the entity (read twice), or reading after try-with-resources closed the Response.","commonSituations":"Caching the InputStream and reading it later outside the request scope; closing the response in a finally block then using the stream; concurrent reads of the same response body from multiple threads; timeouts that close the connection mid-read.","solutions":["Read the entity fully before closing the Response / leaving the try-with-resources block.","Do not read the entity stream twice — buffer it (e.g. readAllBytes()) if the content is needed more than once.","Avoid caching the InputStream beyond the response lifecycle; copy to a ByteArrayOutputStream if needed later.","If the stream closes unexpectedly mid-read, check connection timeouts/idle settings on the REST client config."],"exampleFix":"// before\nbyte[] data;\ntry (Response res = client.get()) {\n  data = null;\n}\ndata = res.readEntity(InputStream.class).readAllBytes(); // closed\n// after\nbyte[] data;\ntry (Response res = client.get()) {\n  data = res.readEntity(InputStream.class).readAllBytes();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"byte[] data;\ntry (Response res = client.target(uri).request().get()) {\n  try (InputStream in = res.readEntity(InputStream.class)) {\n    data = in.readAllBytes();\n  }\n} catch (IOException e) {\n  if (\"Stream is closed\".equals(e.getMessage())) {\n    // re-issue the request; never reuse the cached stream\n    data = reissueRequest();\n  } else { throw new UncheckedIOException(e); }\n}","preventionTips":["Consume the body inside the response's try-with-resources scope","Never read the entity stream twice or cache the InputStream","Copy needed bytes to a byte[]/file before closing the response"],"tags":["rest-client","stream","io","lifecycle"],"backgroundTag":"stream-closed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}