How to server a .html file for a custom HTTP 502 error for a reverse proxy?

1. The problem I’m having:

Everything works, except when the reverse proxy server is down, I would like to show a more advanced error, my goal is to read and output the file /www/html/502.html instead of my current static Bad gateway message in the config.

2. Error messages and/or full log output:

No errors.

3. Caddy version:

v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=

4. How I installed and ran Caddy:

a. System environment:

Docker

b. Command:

Docker, through Portainer

c. Service/unit/compose file:

version: "3.9"

services:
  app:
    restart: unless-stopped
    image: caddy:2.9.1
    ports:
      - 444:444
    volumes:
      - /var/docker_data/caddy/Caddyfile:/etc/caddy/Caddyfile
      - /var/docker_data/caddy/502.html:/www/html/502.html
      - /var/docker_data/caddy/data:/data
      - /var/docker_data/caddy/config:/config
      - /var/docker_data/caddy/certs:/certs
    deploy:
      resources:
        limits:
          memory: 2048M

d. My complete Caddy config:

(retry_rules) {
	lb_retries 5
	lb_try_duration 5s
}

(proxy_error) {
	handle_errors {
		@502 expression `{err.status_code} in [502]`
		handle @502 {
			header Content-Type text/html
			respond "<h1>Bad gateway</h1>" 502
		}
	}
}

test.com {
	reverse_proxy web_test-app-1:8080 {
		import retry_rules
	}

	import proxy_error
}

:444 {
	header Content-Type text/html
	respond "<h1>Not Found</h1>" 404
}

Have you tried using file_server in the handle block inside handle_errors?

I tried to serve the file, but I get stock in a infinite loop with this:

(proxy_error) {
	handle_errors {
		@502 expression `{err.status_code} in [502]`
		handle @502 {
			root * /www/html/502.html
			file_server
		}
	}
}

This is your issue. You cannot root to a file. You root to a directory.

Try

handle_errors 5xx {
	try_files /srv/www/{err.status_code}.html fallback.html
	file_server
}
1 Like

I tried that and now it “handles” the error in a way of only showing a white screen instead of infinite loops. The correct HTTP status is shown in DevTools. No clear error more than that upstream was not responding in the logs of the container.

I also tried to just change the command root... to try_files ... but it’s the same a white screen

(proxy_error) {
	handle_errors {
		@502 expression `{err.status_code} in [502]`
		handle @502 {
			try_files /www/html/502.html fallback.html
			file_server
		}
	}
}

I also tried without file_server and it’s the same.

Enable debug logs by adding debug in the global options section, enable access logs by adding log within the site block, make a request, and share the request, response, and Caddy logs.

After some tinkering I got it working with this.
Unsure if it’s the correct way or not but I get the expected result.

(proxy_error) {
	handle_errors {
		@502 expression `{err.status_code} in [502]`
		handle @502 {
			root * /www/html
			rewrite * /502.html
			file_server
		}
	}
}