prestodb/presto · error · PageTransportErrorException

Expected response code to be 200, but was %s:%n%s

Error message

Expected response code to be 200, but was %s:%n%s

What it means

The HTTP task client expects a 200 OK from the Spark task server; any other status raises PageTransportErrorException with the actual response code and body. The body text is decoded best-effort (exceptions while decoding are ignored) to help diagnose the server-side failure.

Source

Thrown at presto-spark-base/src/main/java/com/facebook/presto/spark/execution/http/PrestoSparkHttpTaskClient.java:753

                        ResponseBody responseBody = response.body();
                        if (responseBody != null) {
                            try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseBody.byteStream(), UTF_8))) {
                                // Get up to 1000 lines for debugging
                                for (int i = 0; i < 1000; i++) {
                                    String line = reader.readLine();
                                    // Don't output more than 100KB
                                    if (line == null || body.length() + line.length() > 100 * 1024) {
                                        break;
                                    }
                                    body.append(line + "\n");
                                }
                            }
                        }
                    }
                    catch (RuntimeException | IOException e) {
                        // Ignored. Just return whatever message we were able to decode
                    }
                    throw new PageTransportErrorException(
                            HostAddress.fromUri(request.url().uri()),
                            format("Expected response code to be 200, but was %s:%n%s",
                                    response.code(),
                                    body.toString()));
                }

                // invalid content type can happen when an error page is returned, but is unlikely given the above 200
                String contentType = response.header(CONTENT_TYPE);
                if (contentType == null) {
                    throw new PageTransportErrorException(
                            HostAddress.fromUri(request.url().uri()),
                            format("%s header is not set: %s", CONTENT_TYPE, response));
                }
                if (!mediaTypeMatches(contentType, PRESTO_PAGES_TYPE)) {
                    throw new PageTransportErrorException(
                            HostAddress.fromUri(request.url().uri()),
                            format("Expected %s response from server but got %s", PRESTO_PAGES_TYPE, contentType));
                }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Read the embedded status code and response body to identify the server-side cause
  2. Retry against the correct/current task location — 404 often means the executor was replaced after a retry
  3. Inspect Spark executor logs for the 500's root cause
  4. Check for proxies/interceptors intercepting the request and returning error pages

Example fix

// handle 404 after task retry by refreshing task info
try {
    return taskClient.handle(request);
}
catch (PageTransportErrorException e) {
    if (e.getMessage().contains("Expected response code to be 200, but was 404")) {
        // refetch SqlTask location/status and rebuild the request
    }
    throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify task location is current before calling
TaskInfo info = taskClient.getTaskInfo(taskId);
if (info.getTaskStatus().getState().isDone()) {
    throw new IllegalStateException("task already finished; refetch location");
}

Type guard

null

Try / catch

try {
    return taskClient.handle(request);
}
catch (PageTransportErrorException e) {
    String msg = e.getMessage();
    if (msg.contains("but was 404")) { /* stale task: refetch task status/location */ }
    else if (msg.contains("but was 500")) { /* server-side task failure: read body for cause */ }
    else if (msg.contains("but was 503")) { /* overloaded: retry with backoff */ }
    throw e;
}

Prevention

When it happens

Trigger: Any PrestoSparkHttpTaskClient.handle() call where response.code() != 200 — e.g. task server returns 404 (task not found/already cleaned), 500 (task failure), 503 (overloaded), or an auth/gateway error page.

Common situations: Spark task retries/executors lost causing 404s for stale task locations; task server crashes returning 500; reverse proxy returning error pages; query results requested after task cleanup.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/abd18c06d06fd905. Report an issue: GitHub.