{"record":{"id":"bd54a240d9015f41","repo":"quarkusio/quarkus","slug":"stream-is-closed-bd54a2","errorCode":null,"errorMessage":"Stream is closed","messagePattern":"Stream is closed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxInputStream.java","lineNumber":79,"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        if (continueState == ContinueState.REQUIRED) {\n            continueState = ContinueState.SENT;\n            exchange.request.response().writeContinue();\n        }\n        readIntoBuffer();\n        if (limit > 0 && exchange.request.bytesRead() > limit) {\n            HttpServerResponse response = exchange.request.response();\n            if (response.headWritten()) {\n                //the response has been written, not much we can do\n                exchange.request.connection().close();\n                throw new IOException(\"Request too large\");\n            } else {\n                response.setStatusCode(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE.code());\n                response.headers().add(HttpHeaderNames.CONNECTION, \"close\");\n                response.endHandler(new Handler<Void>() {\n                    @Override\n                    public void handle(Void event) {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxInputStream.java#L61-L97","documentation":"read() was called on a VertxInputStream after the request body stream was closed. Quarkus wraps the Vert.x request body in this InputStream; once closed=true (explicit close() or connection teardown) any further read throws IOException(\"Stream is closed\").","triggerScenarios":"Calling read()/read(byte[],off,len) on the request InputStream after close() was invoked, or after the request/response lifecycle already ended (e.g. reading the body after writing the response or after async dispatch completed).","commonSituations":"Filters or interceptors that close the input stream then downstream code tries to read the body; reading the body twice (e.g. once for logging, once for deserialization) without caching; asynchronous processing that outlives the request.","solutions":["Read the request body exactly once, before any close, and buffer it if it must be consumed more than once.","Check application code for accidental close() of the request InputStream (closing it is not required and poisons further reads).","Ensure the body is fully read during the blocking request phase, not after the response has been sent or the request dispatched.","If caching is needed, wrap with a duplicate/caching filter or use quarkus.http.body-related caching facilities instead of re-reading the raw stream."],"exampleFix":"// before\ntry (InputStream in = request.getInputStream()) {\n    body = in.readAllBytes();\n} // stream closed; later code calls in.read() -> 'Stream is closed'\n// after\nInputStream in = request.getInputStream();\nbyte[] body = in.readAllBytes(); // do NOT close the request stream; reuse bytes as needed","handlingStrategy":"validation","validationCode":"if (in == null) throw new IllegalStateException(\"no request stream\");\n// read body once and cache before any close()\nbyte[] cached = in.readAllBytes();","typeGuard":null,"tryCatchPattern":"try {\n    int n = in.read(buf);\n} catch (IOException e) {\n    if (\"Stream is closed\".equals(e.getMessage())) {\n        // treat as end-of-stream: use previously cached body\n    } else throw e;\n}","preventionTips":["Never call close() on the request InputStream","Read the body once and cache bytes if multiple consumers need it","Consume the body before writing the response or completing async work"],"tags":["io","stream","vertx-http","request-body"],"backgroundTag":"stream-closed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}