quarkusio/quarkus · error · IllegalStateException
Response has been closed
Error message
Response has been closed
What it means
RestResponseImpl.checkClosed throws IllegalStateException when any entity-related method is invoked after the response has been closed, unless the response was buffered. The JAX-RS Response lifecycle forbids access to the entity stream after close(); buffered responses keep their data in memory and are exempt per the TCK.
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/RestResponseImpl.java:210
while ((read = entityStream.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
entityStream.close();
} catch (IOException x) {
throw new UncheckedIOException(x);
}
entityStream = new ByteArrayInputStream(os.toByteArray());
}
buffered = true;
return true;
}
return false;
}
protected void checkClosed() {
// apparently the TCK says that buffered responses don't care about being closed
if (closed && !buffered)
throw new IllegalStateException("Response has been closed");
}
@Override
public void close() {
if (!closed) {
closed = true;
if (entityStream != null) {
try {
entityStream.close();
} catch (IOException e) {
throw new ProcessingException(e);
}
}
}
}
@Override
public MediaType getMediaType() {View on GitHub (pinned to e1c734241f)
Solutions
- Call bufferEntity() before close() if you need the entity afterwards
- Move all entity reads inside the try-with-resources block, before close()
- Do not close the response until entity processing is complete
- Restructure to consume the entity immediately when the response is received
Example fix
// before
try (RestResponse<Foo> r = client.call()) {
// no read here
}
Foo f = r.readEntity(Foo.class); // IllegalStateException
// after
Foo f;
try (RestResponse<Foo> r = client.call()) {
f = r.readEntity(Foo.class);
} Defensive patterns
Strategy: validation
Validate before calling
if (response.isClosed() && !response.isBuffered()) {
throw new IllegalStateException("Refusing to read from closed response");
} Type guard
boolean usable(RestResponse<?> r) {
return r != null && (!r.isClosed() || r.isBuffered());
} Try / catch
try {
return response.readEntity(String.class);
} catch (IllegalStateException e) {
log.warn("Response already closed");
return null;
} Prevention
- Read the entity inside the try-with-resources block
- Call bufferEntity() before close() when deferring reads
- Never pass Response objects across async boundaries after closing
- Consume entity immediately after receiving the response
When it happens
Trigger: Calling getEntity(), readEntity(), hasEntity(), or bufferEntity() after close() has been called on a non-buffered RestResponse; using try-with-resources on a response and then reading the entity outside the block; response auto-closed by a framework/interceptor before your read.
Common situations: try-with-resources pattern where readEntity happens after the resource block; leaking a response across async boundaries after it was closed; reading the entity in a finally or later callback after close.
Related errors
- Request already suspended
- RestClientProxy is closed
- Unsupported RestClientProxy method: ${method}
- Neither baseUri nor baseUrl was specified
- @RegisterClientContextResolver is only supported on static m
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/85be073c1fb6f15f.
Report an issue: GitHub.