SonarSource/sonarqube · error · IllegalStateException
Fail to read response of
Error message
Fail to read response of %s
What it means
OkHttpResponse.content() reads the full response body of a SonarQube WS client response as a String. If reading the OkHttp ResponseBody throws an IOException, it is wrapped in an IllegalStateException with 'Fail to read response of <requestUrl>'. This means the HTTP request succeeded but the body could not be read (stream closed, connection dropped mid-body).
Solutions
- Read content() promptly, exactly once, while the response is open (don't cache the response across calls).
- Retry the whole request — this failure is usually transient.
- Increase OkHttp client read timeouts and enable keep-alive/retry-on-connection-failure.
- Inspect the cause IllegalStateException's IOException for reset vs timeout; check proxy/LB idle timeout settings.
Example fix
// before: body consumed after response closed
String body;
try (Response r = call.execute()) {
bodyFuture.complete(r); // response closed here
}
String content = r.content(); // IllegalStateException
// after: read while open, retry on failure
try (Response r = call.execute()) {
String content = r.content();
} Defensive patterns
Strategy: retry
Validate before calling
// Ensure the response is ok and body present before reading:
if (!response.isSuccessful() || response.contentLength() == -1) { /* handle error path before content() */ } Try / catch
try {
String body = wsResponse.content();
} catch (IllegalStateException e) {
if (e.getCause() instanceof IOException) {
logger.warn("Body read failed for {} — retrying request", e.getMessage());
body = retry(2, backoff(), wsClient::reissueAndRead);
} else throw e;
} Prevention
- Call content() exactly once and while the response is still open.
- Keep OkHttp read timeouts generous for large responses.
- Don't store Response objects for later reading — extract content immediately.
- Tune load balancer/proxy idle timeouts above client read durations.
When it happens
Trigger: Calling content() on a response whose underlying connection was closed/reset before or during body read; consuming the body after the response/connection was already closed or timed out; server aborting the response mid-transfer.
Common situations: Long responses over unstable connections; reading the body twice or after try-with-resources closed the response; server/proxy timeouts cutting large payloads; load balancers resetting idle connections.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Fail to read response of
- Fail to request url:
- Connect timeout must be positive. Got
- Connection to Azure marketplace failed. Details
- Could not parse GitLab answer when creating a project…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/a5851e4fb41f7047.
Report an issue: GitHub.
Appendix: source
Thrown at sonar-ws/src/main/java/org/sonarqube/ws/client/OkHttpResponse.java:90
/**
* Get stream of characters, decoded with the charset
* of the Content-Type header. If that header is either absent or lacks a
* charset, this will attempt to decode the response body as UTF-8.
*/
@Override
public Reader contentReader() {
return okResponse.body().charStream();
}
/**
* Get body content as a String. This response will be automatically closed.
*/
@Override
public String content() {
try (ResponseBody body = okResponse.body()) {
return body.string();
} catch (IOException e) {
throw fail(e);
}
}
private RuntimeException fail(Exception e) {
throw new IllegalStateException("Fail to read response of " + requestUrl(), e);
}
/**
* Equivalent to closing contentReader or contentStream.
*/
@Override
public void close() {
okResponse.close();
}
}
View on GitHub (pinned to 184c821202)