{"record":{"id":"1048cda2daccbe5f","repo":"eclipse-vertx/vert.x","slug":"cannot-set-chunked-after-data-has-been-written-on","errorCode":null,"errorMessage":"Cannot set chunked after data has been written on request","messagePattern":"Cannot set chunked after data has been written on request","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java","lineNumber":189,"sourceCode":"    this.maxRedirectBufferSize = maxRedirectBufferSize;\n    return this;\n  }\n\n  @Override\n  public synchronized int maxRedirectBufferSize() {\n    return maxRedirectBufferSize;\n  }\n\n  @Override\n  public int numberOfRedirections() {\n    return numberOfRedirections;\n  }\n\n  @Override\n  public synchronized HttpClientRequestImpl setChunked(boolean chunked) {\n    checkEnded();\n    if (headersSent) {\n      throw new IllegalStateException(\"Cannot set chunked after data has been written on request\");\n    }\n    // HTTP 1.0 does not support chunking so we ignore this if HTTP 1.0\n    if (version() != io.vertx.core.http.HttpVersion.HTTP_1_0) {\n      this.chunked = chunked;\n    }\n    return this;\n  }\n\n  @Override\n  public synchronized boolean isChunked() {\n    return chunked;\n  }\n\n  @Override\n  public MultiMap headers() {\n    return headers;\n  }\n","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java#L171-L207","documentation":"HttpClientRequestImpl.setChunked throws IllegalStateException once the request headers have already been sent (equivalently, after data has been written and flushed the headers). The transfer-encoding (chunked vs content-length) decision must be made before headers go on the wire, so later changes are rejected.","triggerScenarios":"Calling request.setChunked(true) after write(...) has been invoked (headers implicitly sent), or after an async write completed before setChunked was called; toggling chunked mode mid-body.","commonSituations":"Streaming code that writes first and configures framing afterwards; building a helper that sets chunked lazily after buffering decides to stream; race between write calls on different threads (method is synchronized but ordering still matters).","solutions":["Call setChunked(true) immediately after creating the request and before any write/end call.","Restructure so framing decisions (chunked vs content-length) are made before the first write.","If body size is known upfront, set the Content-Length header instead of using chunked."],"exampleFix":"// before\nrequest.write(buffer);\nrequest.setChunked(true); // IllegalStateException\n// after\nrequest.setChunked(true);\nrequest.write(buffer);","handlingStrategy":"validation","validationCode":"// always set framing before first write\nHttpClientRequest req = client.request(opts).onSuccess(r -> {\n  if (streaming) r.setChunked(true);\n  r.write(body);\n});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure headers and chunked mode before any write/end call.","Wrap request creation in a helper that applies framing first.","Don't interleave writes and framing configuration in async callbacks."],"tags":["http-request","chunked","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}