{"record":{"id":"557d143bc632231b","repo":"prestodb/presto","slug":"response-body-is-null","errorCode":null,"errorMessage":"Response body is null","messagePattern":"Response body is null","errorType":"exception","errorClass":"PageTransportErrorException","httpStatus":null,"severity":"error","filePath":"presto-spark-base/src/main/java/com/facebook/presto/spark/execution/http/PrestoSparkHttpTaskClient.java","lineNumber":780,"sourceCode":"                if (contentType == null) {\n                    throw new PageTransportErrorException(\n                            HostAddress.fromUri(request.url().uri()),\n                            format(\"%s header is not set: %s\", CONTENT_TYPE, response));\n                }\n                if (!mediaTypeMatches(contentType, PRESTO_PAGES_TYPE)) {\n                    throw new PageTransportErrorException(\n                            HostAddress.fromUri(request.url().uri()),\n                            format(\"Expected %s response from server but got %s\", PRESTO_PAGES_TYPE, contentType));\n                }\n\n                String taskInstanceId = getTaskInstanceId(request, response);\n                long token = getToken(request, response);\n                long nextToken = getNextToken(request, response);\n                boolean complete = getComplete(request, response);\n\n                ResponseBody responseBody = response.body();\n                if (responseBody == null) {\n                    throw new PageTransportErrorException(\n                            HostAddress.fromUri(request.url().uri()),\n                            \"Response body is null\");\n                }\n\n                SliceInput input = new InputStreamSliceInput(responseBody.byteStream());\n                List<SerializedPage> pages = ImmutableList.copyOf(readSerializedPages(input));\n                PagesResponse pagesResponse = createPagesResponse(taskInstanceId, token, nextToken, pages, complete);\n                return new PagesBaseResponse(response.code(), convertHeaders(response), pagesResponse);\n            }\n            catch (PageTransportErrorException e) {\n                throw new PageTransportErrorException(\n                        e.getRemoteHost(),\n                        \"Error fetching \" + request.url(),\n                        e);\n            }\n        }\n\n        private static ListMultimap<OkHttpHeaderName, String> convertHeaders(Response response)","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-spark-base/src/main/java/com/facebook/presto/spark/execution/http/PrestoSparkHttpTaskClient.java#L762-L798","documentation":"After all response headers (task instance id, token, complete) validate, the client reads the page payload from the OkHttp response body. OkHttp can legally return a null body, so the client guards it explicitly and throws PageTransportErrorException instead of NPE, because a null body means the server sent no pages data despite the correct content type.","triggerScenarios":"Server returns a response (correct content type and headers) with an empty or body-less message — e.g. a 204-style response or a truncated/empty transfer from the worker.","commonSituations":"Worker crashed mid-response leaving an empty body; HTTP/2 stream reset producing a bodyless response; intermediary (proxy/gateway) dropping the payload while preserving headers.","solutions":["Retry the pages request — a single empty body from a healthy worker is typically transient.","Check the worker logs for a crash between sending headers and writing the body.","Inspect network path (proxies, load balancers, HTTP/2 resets) for payload-dropping intermediaries.","Confirm the worker was not concurrently shut down or replaced (task instance gone) during the fetch."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// cheap pre-check: ensure endpoint responds and looks like a worker\ncurl -sS -o /dev/null -w '%{http_code} %{content_type}' http://worker:port/rest/path","typeGuard":null,"tryCatchPattern":"try {\n    client.getPagesRequest(location, token, ...);\n} catch (PageTransportErrorException e) {\n    // wrap: bounded retry with backoff, then fail the exchange\n    retryWithBackoff(() -> client.getPagesRequest(location, token, ...), 3);\n}","preventionTips":["Retry page fetches a bounded number of times before failing the exchange.","Monitor worker stability; frequent empty bodies indicate crashing workers.","Keep HTTP clients on HTTP/1.1 or test HTTP/2 resets on your network path.","Alert on proxies that alter or drop payloads."],"tags":["http","response-body","spark","page-transport"],"backgroundTag":"page-transport-error","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}