eclipse-vertx/vert.x · error · IllegalStateException
Cannot set chunked after data has been written on request
Error message
Cannot set chunked after data has been written on request
What it means
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.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java:189
this.maxRedirectBufferSize = maxRedirectBufferSize;
return this;
}
@Override
public synchronized int maxRedirectBufferSize() {
return maxRedirectBufferSize;
}
@Override
public int numberOfRedirections() {
return numberOfRedirections;
}
@Override
public synchronized HttpClientRequestImpl setChunked(boolean chunked) {
checkEnded();
if (headersSent) {
throw new IllegalStateException("Cannot set chunked after data has been written on request");
}
// HTTP 1.0 does not support chunking so we ignore this if HTTP 1.0
if (version() != io.vertx.core.http.HttpVersion.HTTP_1_0) {
this.chunked = chunked;
}
return this;
}
@Override
public synchronized boolean isChunked() {
return chunked;
}
@Override
public MultiMap headers() {
return headers;
}
View on GitHub (pinned to fb308bd8c3)
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.
Example fix
// before request.write(buffer); request.setChunked(true); // IllegalStateException // after request.setChunked(true); request.write(buffer);
Defensive patterns
Strategy: validation
Validate before calling
// always set framing before first write
HttpClientRequest req = client.request(opts).onSuccess(r -> {
if (streaming) r.setChunked(true);
r.write(body);
}); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/1048cda2daccbe5f.
Report an issue: GitHub.