Handle_errors seems not working

1. Caddy version (caddy version):

v2.2.0-rc.1

2. How I run Caddy:

a. System environment:

Ubuntu 18.04.5 LTS

b. Command:

service caddy start

c. Service/unit/compose file:

# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target

[Service]
User=root
Group=root
ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
# ExecStart=/usr/bin/caddy run --config /etc/caddy/caddy.json
# ExecReload=/usr/bin/caddy reload --config /etc/caddy/caddy.json
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddyfile or JSON config:

# {
# 	auto_https disable_redirects
# }

https://haku.site:443 {
	log {
		output file /var/log/caddy/access.log
		level info
	}
	tls /etc/letsencrypt/live/haku.site/fullchain.pem /etc/letsencrypt/live/haku.site/privkey.pem {
		protocols tls1.2
	}
	handle_errors {
		rewrite * /404
		reverse_proxy localhost:3000
	}
	reverse_proxy /split_one http://localhost:12096 {
		header_up Host {http.request.host}
		header_up X-Forwarded-For {http.request.remote.host}
		transport http {
			versions h2c
		}
	}
	reverse_proxy /split_two localhost:22096 {
		header_up Host {http.request.host}
		header_up X-Forwarded-For {http.request.remote.host}
	}
	reverse_proxy * localhost:3000 {
		header_up Upgrade {header.upgrade}
		header_up Host {host}
	}
}

3. The problem I’m having:

Under certain circumstances, visiting the first two backend (match with path /split_xxx) will get a 400 or 404 respond. By setting the “handle_errors”, I assume caddy will visit the third backedn with “/404” path and return a dynamic pretty error page when 400 or 404 respond is returned by the first two. But actually caddy just pass the original 400 or 404 error respond to client.
Could the “handle_errors” settings be used to accomplish such needs? Or the config was somehow wrong?

4. Error messages and/or full log output:

No relevant error messages was provided by journalctl -u caddy
caddy log file:
{"level":"error","ts":1599284371.8765345,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_addr":"xxx.xxx.xxx.xxx:xxxxx","proto":"HTTP/2.0","method":"GET","host":"haku.site","uri":"/split_two","headers":{"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"],"Accept-Language":["zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7"],"Sec-Fetch-Dest":["document"],"Accept-Encoding":["gzip, deflate, br"],"Cache-Control":["max-age=0"],"Dnt":["1"],"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.9"],"Sec-Fetch-Site":["none"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-User":["?1"]},"tls":{"resumed":true,"version":772,"cipher_suite":4865,"proto":"h2","proto_mutual":true,"server_name":"haku.site"}},"common_log":"xxx.xxx.xxx.xxx - - [05/Sep/2020:05:39:31 +0000] \"GET /split_two HTTP/2.0\" 400 12","duration":0.000854732,"size":12,"status":400,"resp_headers":{"Server":["Caddy"],"Content-Length":["12"],"Content-Type":["text/plain; charset=utf-8"],"Sec-Websocket-Version":["13"],"X-Content-Type-Options":["nosniff"],"Date":["Sat, 05 Sep 2020 05:39:31 GMT"]}}

5. What I already tried:

handle_errors{
  @400 {
    expression {http.error.status_code} == '400'
  }
  rewrite @400 /404
  reverse_proxy localhost:3000
}
handle_errors{
  rewrite /split_two /404
  reverse_proxy localhost:3000
}

6. Links to relevant resources:

handle_errors only handles errors generated by Caddy itself, not errors from proxies. Caddy doesn’t consider errors from a proxied service as exceptional.

That said, it is possible to do this with JSON configuration currently by using the handle_response option of the reverse_proxy handler, but this hasn’t been added to the Caddyfile yet (because it’s a bit tricky to implement).

There’s an open issue for Caddyfile support here:

https://github.com/caddyserver/caddy/issues/3707

1 Like

Thanks for answering!

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