prestodb/presto · error · PageTransportErrorException

Expected %s response from server but got %s

Error message

Expected %s response from server but got %s

What it means

PrestoSparkHttpTaskClient validates every HTTP response it downloads pages from: the response must declare Content-Type application/vnd.presto.pages (PRESTO_PAGES_TYPE). If the header is absent or a different media type is returned (e.g. an HTML error page or JSON error), it wraps it in a PageTransportErrorException so the caller treats the endpoint as speaking the wrong protocol rather than returning bad data.

Source

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

                    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));
                }

                String taskInstanceId = getTaskInstanceId(request, response);
                long token = getToken(request, response);
                long nextToken = getNextToken(request, response);
                boolean complete = getComplete(request, response);

                ResponseBody responseBody = response.body();
                if (responseBody == null) {
                    throw new PageTransportErrorException(
                            HostAddress.fromUri(request.url().uri()),
                            "Response body is null");
                }

                SliceInput input = new InputStreamSliceInput(responseBody.byteStream());
                List<SerializedPage> pages = ImmutableList.copyOf(readSerializedPages(input));

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check what the remote actually returned: log/inspect the %s value in the message to see the unexpected content type.
  2. Verify the target server is a genuine Presto native worker on the expected port, not a proxy or another service.
  3. Ensure client and server Presto versions match (same pages serialization protocol).
  4. If a proxy is in the path, bypass it or configure it to pass the response through unchanged (no content-type rewriting, no HTML error interstitials).
  5. Retry the request; transient worker failures can momentarily return error bodies instead of pages.
Defensive patterns

Strategy: validation

Validate before calling

// before reading pages, check the declared content type
String contentType = response.header("Content-Type");
if (contentType == null || !contentType.contains("application/vnd.presto.pages")) {
    throw new IllegalStateException("Non-pages response from " + request.url() + ": " + contentType);
}

Type guard

// narrowing guard for a valid pages response
boolean isPagesResponse(Response r) {
    String ct = r.header("Content-Type");
    return ct != null && ct.trim().startsWith("application/vnd.presto.pages");
}

Try / catch

try {
    PagesBaseResponse resp = client.getPagesRequest(...);
} catch (PageTransportErrorException e) {
    if (e.getMessage() != null && e.getMessage().contains("Expected")) {
        // wrong content type: re-discover a healthy worker and retry
    }
}

Prevention

When it happens

Trigger: Calling the pages-acquire endpoint (getPagesRequest) and the server replies 200 OK but with a Content-Type other than application/vnd.presto.pages — e.g. an error page from a proxy, a JSON-encoded failure from the native worker, or a custom serializer writing the wrong MIME type.

Common situations: A reverse proxy or load balancer intercepts the request and returns an HTML 4xx/5xx page with text/html; a Presto version mismatch where the Spark-side worker returns pages encoded as JSON instead of the Presto pages media type; a misconfigured native worker binary that does not use Smile/pages serialization.

Related errors


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