quarkusio/quarkus · error · IllegalStateException
A REST Client RestResponse object was returned from a server
Error message
A REST Client RestResponse object was returned from a server endpoint. This is not supported because it carries connection-specific headers that are not suitable for forwarding. Please create a new RestResponse by extracting the status, entity and headers you need.
What it means
Same family as the client-Response case but for org.jboss.resteasy.reactive.client.RestResponse: a server endpoint returned the RestResponse instance obtained from a REST Client call (RestResponseImpl flagged as client response). Its connection-specific headers make it unsuitable for direct forwarding, so IllegalStateException is thrown.
Source
Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/ResponseHandler.java:104
if (existing.getMediaType() != null) {
requestContext.setResponseContentType(existing.getMediaType());
mediaTypeAlreadyExists = true;
}
EncodedMediaType produces = requestContext.getResponseContentType();
if (!mediaTypeAlreadyExists && (produces != null) && (responseBuilder.getEntity() != null)) {
responseBuilder.header(HttpHeaders.CONTENT_TYPE, produces.toString());
}
if ((responseBuilder instanceof ResponseBuilderImpl)) {
// avoid unnecessary copying of HTTP headers from the Builder to the Response
requestContext
.setResponse(
new LazyResponse.Existing(((ResponseBuilderImpl) responseBuilder).build(false)));
} else {
requestContext.setResponse(new LazyResponse.Existing(responseBuilder.build()));
}
} else if (result instanceof RestResponse<?> existing) {
if (existing instanceof RestResponseImpl<?> restResponseImpl && restResponseImpl.isClientResponse()) {
throw new IllegalStateException(
"A REST Client RestResponse object was returned from a server endpoint. "
+ "This is not supported because it carries connection-specific headers "
+ "that are not suitable for forwarding. "
+ "Please create a new RestResponse by extracting the status, entity and headers you need.");
}
boolean mediaTypeAlreadyExists = false;
//we already have a response
//set it explicitly
ResponseBuilderImpl responseBuilder;
if (existing.getEntity() instanceof GenericEntity<?> genericEntity) {
requestContext.setGenericReturnType(genericEntity.getType());
responseBuilder = fromResponse(existing);
responseBuilder.entity(genericEntity.getEntity());
} else {
//TODO: super inefficient
responseBuilder = fromResponse(existing);
if ((result instanceof RestResponseImpl<?> responseImpl)) {
// needed in order to preserve entity annotationsView on GitHub (pinned to e1c734241f)
Solutions
- Unwrap and rebuild: return the entity (existing.getEntity()) or a new server Response carrying extracted status/headers
- Use existing.readEntity(Class) to consume the body, then build a fresh Response
- Change the resource method's return type to the entity type rather than RestResponse
- If header forwarding is needed, copy selected headers explicitly into a new Response
Example fix
// before
@GET
public RestResponse<String> call() {
return client.get(); // client RestResponse
}
// after
@GET
public Response call() {
RestResponse<String> existing = client.get();
return Response.ok(existing.readEntity(String.class)).build();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (result instanceof RestResponseImpl<?> r && r.isClientResponse()) result = Response.ok(r.readEntity(Object.class)).build();
Type guard
static boolean isServerRestResponse(RestResponse<?> r) {
return !(r instanceof org.jboss.resteasy.reactive.client.impl.RestResponseImpl<?> impl && impl.isClientResponse());
} Try / catch
try { return proxy(); } catch (IllegalStateException e) { if (e.getMessage().contains("REST Client RestResponse")) { return Response.ok(clientResp.readEntity(String.class)).build(); } throw e; } Prevention
- Return the entity type, not RestResponse, from resource methods
- Unwrap client RestResponse with readEntity before returning
- Never forward client responses verbatim
When it happens
Trigger: A resource method returns the RestResponse<T> received from a MicroProfile/REST Client call, e.g. `return myClient.call();` where the client method returns RestResponse<String>.
Common situations: Service-to-service proxy endpoints; generic wrappers where RestResponse<T> is the return type both client-side and expected server-side; copy-paste between client and server APIs.
Related errors
- A REST Client Response object was returned from a server end
- Unsupported RestClientProxy method: ${method}
- proxyHost must not be null
- Invalid port number
- Invalid proxy string. Expected <hostname>:<port>, found '${p
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2c4be4edebc81ce9.
Report an issue: GitHub.