How do I handle a 502 response with another directive?

1. The problem I’m having:

I want to reverse_proxy a specific path to a specific locally running server, BUT if the local server happens to not be running, I want to automatically reverse_proxy that request to a remote server. In essence, I’m trying to do:

reverse_proxy /some-path localhost:51501 {
  @502 status 502
  handle_response @502 {
    reverse_proxy https://somewhere-else/
  }
}

I am getting the 502 error when I visit /some-path, but that is not resulting in the second reverse_proxy to somewhere else.

2. Error messages and/or full log output:

2024/08/07 21:08:44.026	ERROR	http.log.error	dial tcp [::1]:51501: connect: connection refused	{"request": {"remote_ip": "127.0.0.1", "remote_port": "53818", "client_ip": "127.0.0.1", "proto": "HTTP/2.0", "method": "GET", "host": "localhost:5150", "uri": "/some-path", "headers": {"Sec-Fetch-User": ["?1"], "Accept-Encoding": ["gzip, deflate, br, zstd"], "Cookie": ["REDACTED"], "Sec-Ch-Ua-Mobile": ["?0"], "Sec-Ch-Ua-Platform": ["\"macOS\""], "Sec-Fetch-Site": ["none"], "Cache-Control": ["max-age=0"], "Sec-Ch-Ua": ["\"Chromium\";v=\"127\", \"Not)A;Brand\";v=\"99\""], "Sec-Fetch-Dest": ["document"], "Accept-Language": ["en-US,en;q=0.9"], "Priority": ["u=0, i"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"], "Sec-Fetch-Mode": ["navigate"], "User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"], "Dnt": ["1"], "Upgrade-Insecure-Requests": ["1"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "server_name": "local.mvnapp.net"}}, "duration": 0.001122916, "status": 502, "err_id": "7tb86re41", "err_trace": "reverseproxy.statusError (reverseproxy.go:1269)"}

3. Caddy version:

2.8.4

4. How I installed and ran Caddy:

brew update
brew install caddy

a. System environment:

MacOS 14.4.1

b. Command:

caddy run

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

localhost:5150 {
	reverse_proxy /some-path localhost:51501 {
		@502 status 502
		handle_response @502 {
			reverse_proxy https://www.qa2.mvnapp.net {
				header_up Host {upstream_hostport}
			}
		}
	}
}

I’ve also just tried with a simple response and that also had the same result:

localhost:5150 {
	reverse_proxy /some-path localhost:51501 {
		@502 status 502
		handle_response @502 {
			respond "wahahaha"
		}
	}
}

5. Links to relevant resources:

Howdy @onlywei, welcome to the Caddy community!

Off the top of my head, I think handle_response only intercepts responses from upstream. If the connection is refused, then the 502 isn’t returned from upstream, it’s actually emitted by Caddy itself and I’m thinking it probably wouldn’t get caught by the reverse proxy handler.

If that’s the case then what you want is actually probably handle_errors (Caddyfile directive) — Caddy Documentation. That directive explicitly won’t handle any errors returned by upstream but I think it should deal with the 502 that Caddy generates.

2 Likes

handle_errors 502 worked!! Thank you!

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.