Proxy-Status proxy response
Provides structured information about what an intermediary proxy did with a request — errors, forwarding decisions, and why things failed.
What it does
Proxy-Status gives structured information about what an intermediary proxy (CDN, load balancer, reverse proxy) did with a request — particularly what went wrong and why. It's designed to surface proxy-level errors in a machine-readable format so clients and monitoring systems can understand them without parsing opaque HTML error pages.
Think of it as Via (which tracks the path) combined with Cache-Status (which tracks cache decisions) for the error and forwarding decision case.
Syntax
Proxy-Status: <proxy-name>; <parameter>[; <parameter>]
Proxy-Status: <proxy1>; <param>, <proxy2>; <param>
Examples:
Proxy-Status: ExampleCDN; error=connection_timeout
Proxy-Status: ExampleCDN; next-hop=origin.example.com; next-hop-fetches=1; error=dns_timeout
Proxy-Status: cdn; error=http_request_error; details="upstream returned 502"
Parameters
| Parameter | Meaning |
|---|---|
error=<type> |
What type of error occurred (see error types below) |
next-hop=<host> |
The upstream server this proxy attempted to connect to |
next-hop-fetches=<n> |
Number of upstream fetch attempts |
next-protocol=<proto> |
Protocol used to connect to next hop |
received-status=<code> |
HTTP status the proxy received from upstream |
details=<string> |
Human-readable detail for debugging |
by=<proxy> |
Identifier for the proxy generating this entry |
Error types
| Error type | Meaning |
|---|---|
dns_timeout |
DNS resolution timed out |
dns_error |
DNS resolution failed |
destination_not_found |
Upstream not configured or found |
destination_unavailable |
Upstream unreachable |
connection_timeout |
TCP connection timed out |
connection_refused |
TCP connection refused |
connection_terminated |
Connection dropped mid-request |
http_request_error |
Error in the upstream HTTP request |
http_response_incomplete |
Upstream closed connection before finishing |
http_response_header_section_size |
Response headers too large |
tls_error |
TLS handshake failed |
proxy_loop_detected |
Loop detected (see CDN-Loop) |
http_response_timeout |
Upstream didn't respond in time |
Proxy-Status vs Via vs Cache-Status
These three headers cover different aspects of proxy behaviour:
| Header | Answers |
|---|---|
Via |
Which proxies did this request pass through? |
Cache-Status |
What did each cache do (hit/miss/stale)? |
Proxy-Status |
What errors or decisions occurred at each proxy? |
They're complementary. A full picture of a request's journey through CDN infrastructure might include all three.
When you'll see it
Proxy-Status is most useful on error responses (5xx) where the proxy failed to connect to the origin, or on responses where something unexpected happened. A CDN returning 502 Bad Gateway with Proxy-Status: cdn; error=connection_timeout; next-hop=origin.example.com tells you exactly what happened: CDN tried to reach your origin, TCP connection timed out.
Without Proxy-Status, debugging a 502 from a CDN involves guessing whether it was a DNS issue, a timeout, a TLS error, or the origin actually returning 502.
Adoption status
RFC 9209 was published in June 2022. As of mid-2026, adoption is growing but not yet universal. Fastly and Cloudflare have added support. Check your CDN documentation. Proxy-Status is more likely to appear on error responses than success responses in current implementations.
Real-world examples
CDN couldn't reach origin (connection timeout):
HTTP/1.1 502 Bad Gateway
Proxy-Status: MyCDN; error=connection_timeout; next-hop=origin.example.com:443; next-hop-fetches=3
DNS resolution failure:
HTTP/1.1 502 Bad Gateway
Proxy-Status: MyCDN; error=dns_timeout; next-hop=origin.example.com; details="DNS query timed out after 5s"
Origin returned an error:
HTTP/1.1 502 Bad Gateway
Proxy-Status: MyCDN; received-status=500; next-hop=origin.example.com
Successful request (for informational purposes):
HTTP/1.1 200 OK
Proxy-Status: MyCDN; next-hop=origin.example.com; next-hop-fetches=1
Cache-Status: MyCDN; fwd=miss; stored
FAQ
Should my application server set Proxy-Status?
No — Proxy-Status is set by intermediary proxies (CDNs, load balancers, reverse proxies), not by origin application servers. If you're building a proxy or gateway service, yes. Otherwise, it's infrastructure infrastructure's responsibility.
How does this help debugging?
Enormously. Before Proxy-Status, getting a 502 from a CDN and figuring out whether it was a DNS failure, TCP timeout, TLS error, or origin-side 500 required reading CDN-specific dashboards, logs, or calling support. With Proxy-Status, the error type is right in the response header — machine-readable and visible in your browser's DevTools Network tab immediately.
Fun fact
Proxy-Status (RFC 9209) was co-authored by engineers from Fastly and Cloudflare, the same companies behind CDN-Loop (RFC 8586). There's a pattern here: CDN vendors getting tired of debugging the same class of problems through opaque error responses and proprietary tooling, then collaborating on an RFC to standardise the information they were already surfacing in proprietary headers. Proxy-Status consolidates what Fastly was putting in X-Served-By and X-Cache, what Cloudflare was putting in CF-Ray and error pages, and what engineers were reading from server logs — all into one structured header.