{"record":{"id":"20148098c31d4444","repo":"quarkusio/quarkus","slug":"cannot-write-more-than-one-piece-of-async-data-at","errorCode":null,"errorMessage":"Cannot write more than one piece of async data at a time","messagePattern":"Cannot write more than one piece of async data at a time","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-servlet/runtime/src/main/java/io/quarkus/resteasy/reactive/server/servlet/runtime/ServletRequestContext.java","lineNumber":516,"sourceCode":"        return this;\n    }\n\n    @Override\n    public ServerHttpResponse write(byte[] data, Consumer<Throwable> asyncResultHandler) {\n        if (asyncWriteData != null) {\n            asyncResultHandler.accept(new IllegalStateException(\"Cannot write before data has all been written\"));\n        }\n        if (asyncContext == null) {\n            try {\n                response.getOutputStream().write(data);\n                asyncResultHandler.accept(null);\n            } catch (IOException e) {\n                asyncResultHandler.accept(e);\n            }\n        } else {\n            synchronized (this) {\n                if (asyncWriteData != null) {\n                    throw new IllegalStateException(\"Cannot write more than one piece of async data at a time\");\n                }\n                asyncWriteData = data;\n                asyncWriteHandler = asyncResultHandler;\n                if (writeListener == null) {\n                    try {\n                        ServletOutputStream outputStream = response.getOutputStream();\n                        outputStream.setWriteListener(writeListener = new ServletWriteListener(outputStream));\n                    } catch (IOException e) {\n                        asyncResultHandler.accept(e);\n                    }\n                } else {\n                    writeListener.onWritePossible();\n                }\n            }\n        }\n        return this;\n    }\n","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-servlet/runtime/src/main/java/io/quarkus/resteasy/reactive/server/servlet/runtime/ServletRequestContext.java#L498-L534","documentation":"ServletRequestContext (the servlet bridge for RESTEasy Reactive) only supports one outstanding asynchronous write on the servlet output stream at a time. write() throws this IllegalStateException, inside a synchronized block, if another async write (asyncWriteData) is still pending. It protects against interleaving blocking and async response writes.","triggerScenarios":"Calling write(byte[], io.quarkus.vertx.core.runtime.context.SafeWritableOutputStream-like handler) while a previous async write has not completed; calling write twice before the write listener reports completion; concurrent writes from multiple threads on the same response context.","commonSituations":"Custom response streaming code writing chunks without awaiting the async result handler; servlet async write listener not invoked (client slow), so the next write hits the pending slot; mixing blocking and async output APIs on the same request.","solutions":["Wait for the asyncResultHandler callback (success or failure) before issuing the next write","Serialize writes through a single thread or an orderly queue so only one write is in flight","On callback completion, clear asyncWriteData state (the implementation does this) before continuing","If streaming large payloads, use a blocking-safe write loop on a worker thread instead of stacked async writes"],"exampleFix":"// before\nctx.write(chunk1, handler);\nctx.write(chunk2, handler); // throws\n// after\nctx.write(chunk1, handler);\nhandler.thenRun(() -> ctx.write(chunk2, handler));","handlingStrategy":"try-catch","validationCode":"synchronized (ctx) {\n    boolean safe = (pendingWrites.get(ctx) == 0); // track in-flight writes externally\n}\n// only issue next write when previous asyncResultHandler completed","typeGuard":"boolean canWrite(ServletRequestContext ctx) {\n    return !ctxHasPendingAsyncWrite(ctx); // maintain your own in-flight flag\n}","tryCatchPattern":"try {\n    ctx.write(data, handler);\n} catch (IllegalStateException e) {\n    queue.offer(data); // retry after current write completes\n}","preventionTips":["Write the next chunk only inside the async result handler callback","Never call write concurrently from multiple threads on the same response","Serialize streaming through a single writer/queue","Track outstanding async writes with a counter"],"tags":["resteasy-reactive","servlet","async","concurrency"],"backgroundTag":"concurrent-write-conflict","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"}