Skip to content

fix(proxy): return 504 for upstream timeouts in fail_to_proxy per RFC 9110 - #996

Open
Aditya-9-6 wants to merge 2 commits into
cloudflare:mainfrom
Aditya-9-6:fix/upstream-timeouts-504-mapping
Open

fix(proxy): return 504 for upstream timeouts in fail_to_proxy per RFC 9110#996
Aditya-9-6 wants to merge 2 commits into
cloudflare:mainfrom
Aditya-9-6:fix/upstream-timeouts-504-mapping

Conversation

@Aditya-9-6

Copy link
Copy Markdown

Fixes #980

Problem

In pingora-proxy/src/proxy_trait.rs, fail_to_proxy currently maps all upstream-sourced errors to 502 Bad Gateway:

ErrorSource::Upstream => 502,

Consequently, upstream deadline expiries (ConnectTimedout, TLSHandshakeTimedout, ReadTimedout, WriteTimedout) surface to downstream clients as 502 Bad Gateway.

Per RFC 9110 §15.6.6:

"The 504 (Gateway Timeout) status code indicates that the server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request."

Both NGINX and Envoy map upstream connection, read, and write deadline expiries to 504. In Pingora, returning 502 prevents monitoring and clients from distinguishing between slow/hung upstreams and broken/refused upstreams.

Solution

  1. Extract default_fail_to_proxy_status(e: &Error) -> u16:
    Extracts the default status mapping into a public helper function so custom proxy implementations can reuse the standard mapping without copying the whole match structure.
  2. RFC 9110-compliant 504 Mapping:
    • Upstream deadline expiries (ConnectTimedout, TLSHandshakeTimedout, ReadTimedout, WriteTimedout) now map to 504 Gateway Timeout.
    • All other upstream failures (connection refused, no route, invalid certificates, broken frames) continue to return 502 Bad Gateway.
    • Downstream and internal status mappings remain completely unchanged.
  3. Unit Tests:
    Added unit tests in proxy_trait.rs covering all upstream timeout branches, non-timeout upstream failures, downstream disconnections (status 0), and explicit HTTPStatus preservation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upstream timeouts (connect/read/write) synthesize 502 instead of 504 in fail_to_proxy's default status mapping

1 participant