prestodb/presto · error · ProxyException

Bad status code from remote Presto server

Error message

Bad status code from remote Presto server: %s: %s

What it means

The proxy expects HTTP 200 (or 204) from the remote Presto server. Any other status is wrapped in a ProxyException with the status code and the response body embedded in the message. It means the backend rejected or failed the request at the HTTP level.

Solutions

  1. Read the status code and body in the message to identify the backend's complaint.
  2. Fix authentication if 401/403 (check forwarded credentials/bearer token setup).
  3. Correct the remote server URI/port if 404.
  4. If 500/503, check backend Presto coordinator logs and health.
Defensive patterns

Strategy: try-catch

Validate before calling

// check the endpoint returns 200 before issuing real work
const probe = await fetch(backendUri + path, { method: "HEAD", headers });
if (![200, 204].includes(probe.status)) throw new Error("Backend status " + probe.status);

Try / catch

try {
  return await proxyCall(req);
} catch (e) {
  const m = /Bad status code .*?: (\d+):/.exec(String(e.message));
  if (m) {
    const status = Number(m[1]);
    if (status === 401 || status === 403) refreshCredentials();
    else if (status === 503) scheduleRetry();
  }
  throw e;
}

Prevention

When it happens

Trigger: Remote server returned e.g. 401/403 (auth), 404 (wrong URI/path), 500 (internal error), or 503 (unavailable) for a proxied call; the body is included via readBody(response).

Common situations: Expired/missing bearer token forwarded to backend; wrong remote server port or context path; backend returning 503 during restart or overload.

Related errors


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

Appendix: source

Thrown at presto-proxy/src/main/java/com/facebook/presto/proxy/ProxyResponseHandler.java:53

        implements ResponseHandler<ProxyResponse, RuntimeException>
{
    private static final MediaType MEDIA_TYPE_JSON = MediaType.create("application", "json");

    @Override
    public ProxyResponse handleException(Request request, Exception exception)
    {
        throw new ProxyException("Request to remote Presto server failed", exception);
    }

    @Override
    public ProxyResponse handle(Request request, Response response)
    {
        if (response.getStatusCode() == NO_CONTENT.code()) {
            return new ProxyResponse(response.getHeaders(), new byte[0]);
        }

        if (response.getStatusCode() != OK.code()) {
            throw new ProxyException(format("Bad status code from remote Presto server: %s: %s", response.getStatusCode(), readBody(response)));
        }

        String contentType = response.getHeader(CONTENT_TYPE);
        if (contentType == null) {
            throw new ProxyException("No Content-Type set in response from remote Presto server");
        }
        if (!MediaType.parse(contentType).is(MEDIA_TYPE_JSON)) {
            throw new ProxyException("Bad Content-Type from remote Presto server:" + contentType);
        }

        try {
            return new ProxyResponse(response.getHeaders(), toByteArray(response.getInputStream()));
        }
        catch (IOException e) {
            throw new ProxyException("Failed reading response from remote Presto server", e);
        }
    }

View on GitHub (pinned to 55bb57d202)