{"record":{"id":"ecc1e294828baf8d","repo":"apache/iceberg","slug":"failed-to-convert-http-response-body-to-string","errorCode":null,"errorMessage":"Failed to convert HTTP response body to string","messagePattern":"Failed to convert HTTP response body to string","errorType":"exception","errorClass":"RESTException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/HTTPClient.java","lineNumber":176,"sourceCode":"    this.isRootClient = false;\n  }\n\n  @Override\n  public HTTPClient withAuthSession(AuthSession session) {\n    Preconditions.checkNotNull(session, \"Invalid auth session: null\");\n    return new HTTPClient(this, session);\n  }\n\n  private static String extractResponseBodyAsString(ClassicHttpResponse response) {\n    try {\n      if (response.getEntity() == null) {\n        return null;\n      }\n\n      // EntityUtils.toString returns null when HttpEntity.getContent returns null.\n      return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);\n    } catch (IOException | ParseException e) {\n      throw new RESTException(e, \"Failed to convert HTTP response body to string\");\n    }\n  }\n\n  private static boolean isSuccessful(ClassicHttpResponse response) {\n    int code = response.getCode();\n    return code == HttpStatus.SC_OK\n        || code == HttpStatus.SC_ACCEPTED\n        || code == HttpStatus.SC_NO_CONTENT\n        || code == HttpStatus.SC_NOT_MODIFIED;\n  }\n\n  private static ErrorResponse buildDefaultErrorResponse(ClassicHttpResponse response) {\n    String responseReason = response.getReasonPhrase();\n    String message =\n        responseReason != null && !responseReason.isEmpty()\n            ? responseReason\n            : EnglishReasonPhraseCatalog.INSTANCE.getReason(response.getCode(), null /* ignored */);\n    String type = \"RESTException\";","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/HTTPClient.java#L158-L194","documentation":"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.","triggerScenarios":"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.","commonSituations":"Unstable network between client and catalog, load balancers dropping long responses, misconfigured proxies injecting malformed headers, or timeouts closing the socket mid-transfer.","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"],"exampleFix":"// before\n// read timeouts too low for large metadata responses\nconfig.put(\"rest.client.request.timeout.ms\", \"1000\");\n// after\nconfig.put(\"rest.client.request.timeout.ms\", \"60000\");","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  client.execute(request, errorHandler, responseType);\n} catch (RESTException e) {\n  if (e.getCause() instanceof IOException) {\n    retryWithBackoff(request); // transient network failure\n  } else {\n    throw e;\n  }\n}","preventionTips":["Set generous socket/read timeouts for large metadata responses","Avoid proxies that truncate or rewrite REST responses","Retry idempotent reads automatically on connection failures"],"tags":["rest","http-client","network","response-body"],"backgroundTag":"network-request-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}