So currently, the only way to do it is using the still experimental CEL expression matcher feature. Just gave it a quick go, it looks something like this:
handle_errors {
@404 {
expression int({http.error.status_code}) == 404
}
respond @404 "Four Oh Four"
}
Edit: Did a bit more experimentation, this also works:
expression {http.error.status_code} == '404'
There’s some finickiness with types (Caddy placeholders only output strings) and double quotes ("
is parsed by Caddy and gets stripped before it hits CEL), but single quotes '
get passed through just fine and CEL handles it as a string as well.