{"record":{"id":"41e5426475cc6d5d","repo":"quarkusio/quarkus","slug":"failed-to-write-41e542","errorCode":null,"errorMessage":"Failed to write","messagePattern":"Failed to write","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"independent-projects/vertx-utils/src/main/java/io/quarkus/vertx/utils/VertxOutputStream.java","lineNumber":110,"sourceCode":"        if (last && data == null) {\n            response.end();\n            return;\n        }\n        lock.lock();\n        try {\n            awaitWriteable();\n            if (last) {\n                if (!response.ended()) { // can happen when an exception occurs during JSON serialization with Jackson\n                    response.end(createBuffer(data));\n                }\n            } else {\n                response.write(createBuffer(data));\n            }\n        } catch (Exception e) {\n            if (data != null && data.refCnt() > 0) {\n                data.release();\n            }\n            throw new IOException(\"Failed to write\", e);\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    private void awaitWriteable() throws IOException {\n        // is it running in an event loop?\n        if (Context.isOnEventLoopThread()) {\n            // NEVER block the event loop!\n            return;\n        }\n        assert lock.isHeldByCurrentThread();\n        while (response.writeQueueFull()) {\n            if (throwable != null) {\n                throw new IOException(throwable);\n            }\n            if (response.closed()) {\n                throw new IOException(\"Connection has been closed\");","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/vertx-utils/src/main/java/io/quarkus/vertx/utils/VertxOutputStream.java#L92-L128","documentation":"VertxOutputStream.write() forwards data to the underlying Vertx HttpServerResponse while holding a lock; any exception raised by the response write (buffer creation, connection reset, response already ended) is wrapped in an IOException with message 'Failed to write'. The ByteBuf is released before throwing to avoid native memory leaks.","triggerScenarios":"Calling write()/writeBlocking() when the client has disconnected, the response has already ended, the write queue is in a failed state, or the event loop throws while handling the write.","commonSituations":"Clients aborting large downloads mid-stream; browser timeouts on slow server-sent-event responses; proxy/load-balancer idle timeouts closing the connection while the server is still writing.","solutions":["Log the cause (IOException.getCause()) to find the real reason (reset by peer, response ended, etc.)","Check response/closed state and stop streaming when the client disconnects instead of continuing to write","Reduce chunk size or apply backpressure so the write queue is not overwhelmed","Ensure writes are not attempted after the response has been ended elsewhere in the handler"],"exampleFix":"// before\nout.write(chunk); // throws IOException(\"Failed to write\") after client disconnect\n// after\nif (!context.response().closed() && !context.response().ended()) {\n    out.write(chunk);\n} else {\n    out.close();\n    return;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    out.writeBlocking(data);\n} catch (IOException e) {\n    logger.debug(\"Write failed (client likely disconnected): {}\", e.getCause() == null ? e : e.getCause().toString());\n    try { out.close(); } catch (IOException ignored) { }\n}","preventionTips":["Check response closed/ended state before each chunk","Keep writes small so the write queue drains between calls","Log causes at debug level; client disconnects during streaming are routine"],"tags":["io","vertx","http","streaming"],"backgroundTag":"broken-pipe","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"}