eclipse-vertx/vert.x · error · IllegalStateException
Request already complete
Error message
Request already complete
What it means
checkEnded() throws this IllegalStateException whenever an operation that writes or mutates the request (e.g. setStreamPriority) is invoked after the request has already been completed (trailers sent). Once the request is fully sent, its state can no longer change.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/HttpClientRequestImpl.java:606
uri = "/";
}
HttpRequestHead head = new HttpRequestHead(ssl ? "https" : "http", method, uri, headers, authority(), absoluteURI(), traceOperation);
future = stream.writeHead(head, chunked, buff, writeEnd, priority, connect);
} else {
if (buff == null && !end) {
throw new IllegalArgumentException();
}
future = stream.writeChunk(buff, writeEnd);
}
if (end) {
tryComplete();
}
return future;
}
private void checkEnded() {
if (trailersSent) {
throw new IllegalStateException("Request already complete");
}
}
@Override
public synchronized HttpClientRequest setStreamPriority(StreamPriority priority) {
if (headersSent) {
stream.updatePriority(priority);
} else {
this.priority = priority;
}
return this;
}
@Override
public synchronized StreamPriority getStreamPriority() {
return stream.priority();
}
}View on GitHub (pinned to fb308bd8c3)
Solutions
- Reorder code so priority/headers are set before end() is called
- Track request completion (e.g. a boolean or the end future) and skip further mutations once ended
- Only call end() once, from a single code path
Example fix
// before request.end(); request.setStreamPriority(priority); // throws // after request.setStreamPriority(priority); request.end();
Defensive patterns
Strategy: type-guard
Validate before calling
boolean ended = endFuture.isComplete();
if (!ended) { request.setStreamPriority(priority); } Type guard
void safeSetPriority(HttpClientRequest req, StreamPriority p, Future<Void> endFuture) {
if (!endFuture.isComplete()) req.setStreamPriority(p);
} Try / catch
try {
request.setStreamPriority(priority);
} catch (IllegalStateException e) {
// request already complete; ignore or log
} Prevention
- Set priority/headers before calling end()
- Call end() from exactly one code path
- Track completion with the future returned by end()
When it happens
Trigger: Calling setStreamPriority, write, putHeader or similar after end()/end(chunk) has completed, e.g. asynchronously after a delayed callback fires post-completion.
Common situations: Async code that configures the request after awaiting something, while the request already ended due to an error path or early completion; duplicated completion paths calling end twice.
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
- Client is closed
- Response already ended
- Request has already been read
- Already started
- Event Bus is not started
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/9e51fff68291e54d.
Report an issue: GitHub.