quarkusio/quarkus · error · IllegalStateException
Response has been closed
Error message
Response has been closed
What it means
ResponseImpl.checkClosed() throws IllegalStateException when a Response that was closed() and is not buffered is accessed. Once closed, the underlying connection/stream is released, so getEntity, readEntity, hasEntity and bufferEntity refuse to operate. Buffered responses are exempt per the JAX-RS TCK.
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/ResponseImpl.java:190
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
- Read the entity BEFORE closing the response; close in a finally/try-with-resources after consumption.
- Call bufferEntity() before close() if you need to access the entity multiple times or after closing.
- Remove the duplicate close() or the late access; don't share Response objects across async boundaries after closing.
- Restructure so the entity is extracted into a plain object within the response's scope.
Example fix
// before
try (Response response = client.target(url).request().get()) { /* nothing read here */ }
String body = response.readEntity(String.class); // IllegalStateException
// after
String body;
try (Response response = client.target(url).request().get()) {
body = response.readEntity(String.class);
} Defensive patterns
Strategy: try-catch
Validate before calling
// guard before reading
if (response instanceof ResponseImpl) { /* or track closed state yourself */ }
boolean safeToRead = !responseClosed && (buffered || response.hasEntity()); Type guard
boolean canRead(javax.ws.rs.core.Response r) { try { return r.hasEntity(); } catch (IllegalStateException e) { return false; } } Try / catch
try { return response.readEntity(String.class); } catch (IllegalStateException e) { log.warn("Response already closed; re-issue request or buffer beforehand", e); return null; } Prevention
- Read the entity inside the try-with-resources scope before close()
- Call bufferEntity() if you need the entity more than once or after closing
- Don't leak Response objects out of request/async scopes
- Centralize response consumption in one utility method
When it happens
Trigger: Calling readEntity()/getEntity() on a Response after close(); using a Response outside a try-with-resources after it has been auto-closed; accessing a Response in a listener/callback that runs after the request completed.
Common situations: Double-consumption patterns where code closes the response then logs the entity; caching a Response field and reading it later; framework code (filters/interceptors) that closed the response before downstream code reads it.
Related errors
- No content has been set
- Request could not be mapped to type ${genericType != null ?
- Response has been closed
- Dev services for ${request.getName()} requires a startable s
- Can only be called at runtime
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/f45594be6bfbb27d.
Report an issue: GitHub.