apache/iceberg · error · RESTException
Failed to convert HTTP response body to string
Error message
Failed to convert HTTP response body to string
What it means
HTTPClient failed to read and decode an HTTP response body as a UTF-8 string using Apache HttpClient's EntityUtils.toString, wrapping the IOException/ParseException in a RESTException. This typically means the connection was cut off mid-body, the body is not valid per its content type, or the entity stream is broken.
Solutions
- Retry the request — this is usually a transient network interruption
- Check network stability and proxy/timeout configuration between client and catalog
- Inspect the wrapped cause exception (getCause()) to distinguish IOException (connection) from ParseException (headers/content-type)
- Increase client socket/read timeouts if large responses are being cut off
Example fix
// before
// read timeouts too low for large metadata responses
config.put("rest.client.request.timeout.ms", "1000");
// after
config.put("rest.client.request.timeout.ms", "60000"); Defensive patterns
Strategy: retry
Try / catch
try {
client.execute(request, errorHandler, responseType);
} catch (RESTException e) {
if (e.getCause() instanceof IOException) {
retryWithBackoff(request); // transient network failure
} else {
throw e;
}
} Prevention
- Set generous socket/read timeouts for large metadata responses
- Avoid proxies that truncate or rewrite REST responses
- Retry idempotent reads automatically on connection failures
When it happens
Trigger: Any REST catalog response whose entity could not be read — connection reset while streaming the body, invalid Content-Type header causing a ParseException, truncated response from a proxy, or a null/failed entity stream.
Common situations: Unstable network between client and catalog, load balancers dropping long responses, misconfigured proxies injecting malformed headers, or timeouts closing the socket mid-transfer.
Related errors
- Error occurred while processing
- Failed to close HTTP client
- Unhandled error
- Attempted to release already closed HTTP client: key=
- Cannot acquire closed HTTP client
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ecc1e294828baf8d.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/rest/HTTPClient.java:176
this.isRootClient = false;
}
@Override
public HTTPClient withAuthSession(AuthSession session) {
Preconditions.checkNotNull(session, "Invalid auth session: null");
return new HTTPClient(this, session);
}
private static String extractResponseBodyAsString(ClassicHttpResponse response) {
try {
if (response.getEntity() == null) {
return null;
}
// EntityUtils.toString returns null when HttpEntity.getContent returns null.
return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
} catch (IOException | ParseException e) {
throw new RESTException(e, "Failed to convert HTTP response body to string");
}
}
private static boolean isSuccessful(ClassicHttpResponse response) {
int code = response.getCode();
return code == HttpStatus.SC_OK
|| code == HttpStatus.SC_ACCEPTED
|| code == HttpStatus.SC_NO_CONTENT
|| code == HttpStatus.SC_NOT_MODIFIED;
}
private static ErrorResponse buildDefaultErrorResponse(ClassicHttpResponse response) {
String responseReason = response.getReasonPhrase();
String message =
responseReason != null && !responseReason.isEmpty()
? responseReason
: EnglishReasonPhraseCatalog.INSTANCE.getReason(response.getCode(), null /* ignored */);
String type = "RESTException";View on GitHub (pinned to 86d9c8fc54)