1. The problem I’m having:
I host a website grav.munn.me and when I go to the ‘default’ site, I get a ERR_HTTP2_PROTOCOL_ERROR. Things like Grav Admin Login | Thomas Munn' Home Page seem to work fine. I did some research, and it appears that the problem seems to be with php-fpm returning an incomplete response. I did look at some of the other posts, and I suspect it has to do with the content-length not being specified. Regardles, I have been getting these errors since upgrading to any verison newer than 2.6x. CURL responses seem ‘fine’ but most browsers (chrome, firefox, etc) seem to intermittently work or give me this error when accessing the root or other pages within the site.
q
2. Error messages and/or full log output:
{"level":"error","ts":1741995490.7439272,"logger":"http.handlers.reverse_proxy","msg":"aborting with incomplete response","upstream":"127.0.0.1:9000","duration":0.07376484,"request":{"remote_ip":"71.142.123.82","remote_port":"31801","client_ip":"71.142.123.82","proto":"HTTP/2.0","method":"GET","host":"grav.munn.me","uri":"/index.php","headers":{"Priority":["u=0, i"],"Sec-Fetch-Site":["none"],"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-User":["?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.7"],"Accept-Language":["en-US,en;q=0.9"],"Cache-Control":["max-age=0"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Cookie":["REDACTED"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["grav.munn.me"],"If-None-Match":["\"8c0fc8a200e4f6588ffa74e078687c5c\""],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36"],"Sec-Fetch-Dest":["document"],"X-Forwarded-For":["71.142.123.82"],"Sec-Ch-Ua-Mobile":["?0"],"Sec-Ch-Ua":["\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\""],"Sec-Fetch-Mode":["navigate"],"Sec-Ch-Ua-Platform":["\"Linux\""]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"grav.munn.me"}},"error":"writing: http: request method or response status code does not allow body"}
3. Caddy version:
v2.8.4
4. How I installed and ran Caddy:
apk add caddy
rc-update add caddy default
a. System environment:
Linux web01 6.12.17-0-virt #1-Alpine SMP PREEMPT_DYNAMIC 2025-02-27 18:31:59 x86_64 Linux
Running on alpine 3.21 x86_64
b. Command:
service caddy start
c. Service/unit/compose file:
#!/sbin/openrc-run
supervisor=supervise-daemon
name="Caddy web server"
description="Fast, multi-platform web server with automatic HTTPS"
description_checkconfig="Check configuration"
description_reload="Reload configuration without downtime"
: ${caddy_opts:="--config /etc/caddy/Caddyfile --adapter caddyfile"}
command=/usr/sbin/caddy
command_args="run $caddy_opts"
command_user=caddy:caddy
extra_commands="checkconfig"
extra_started_commands="reload"
capabilities="^cap_net_bind_service"
depend() {
need net localmount
after firewall
}
checkconfig() {
ebegin "Checking configuration for $name"
su ${command_user%:*} -s /bin/sh -c "$command validate $caddy_opts"
eend $?
}
reload() {
ebegin "Reloading $name"
su ${command_user%:*} -s /bin/sh -c "$command reload --force $caddy_opts"
eend $?
}
stop_pre() {
if [ "$RC_CMD" = restart ]; then
checkconfig || return $?
fi
}
d. My complete Caddy config:
{
log {
level debug
output file /var/log/caddy/caddydebug.log
}
}
recipe.munn.me {
root * /recipe
file_server {
precompressed zstd br gzip
}
tls thomas@munn.me
log {
output file /home/caddy/logs/recipes.log {
roll_keep 7
roll_keep_for 14d
}
}
encode {
zstd
}
}
grav.munn.me {
root * /grav
file_server
php_fastcgi 127.0.0.1:9000 {
request_buffers 4k
}
header {
-Server
-x-powered-by
Permissions-Policy interest-cohort=()
strict-transport-security "max-age=31536000; include-subdomains;"
X-Frame-Options DENY
X-Content-Type-Options nosniff
X-XSS-Protection "1; mode=block"
Referrer-Policy no-referrer-when-downgrade
}
tls thomas@munn.me
log {
output file /home/caddy/logs/grav.log {
roll keep 7
roll_keep_for 14d
}
}
encode {
zstd
gzip
}
@denytl {
path_regexp /(\.git|cache|bin|logs|backups|tests)/.*
}
@denydangerousSystemVendor {
path_regexp /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$
}
@denyUser {
path_regexp /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$
}
@denyroots {
path_regexp /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess)
}
respond @denytl 403
respond @denydangerousSystemVendor 403
respond @denyUser 403
respond @denyroots 403
}
calendar.munn.me {
log {
output file /home/caddy/logs/calendar.log {
roll keep 7
roll_keep_for 14d
}
level debug
}
redir /radicale /radicale/
handle /radicale/* {
uri strip_prefix /radicale
}
reverse_proxy localhost:5232 {
header_up X-Script-Name /radicale
}
}
whittingtonpark.org {
root * /hoa
file_server
php_fastcgi 127.0.0.1:9000
tls thomas@munn.me
log {
output file /home/caddy/logs/hoa.log {
roll keep 7
roll_keep_for 14d
}
}
encode {
zstd
gzip
}
@denytl {
path_regexp /(\.git|cache|bin|logs|backups|tests)/.*
}
@denydangerousSystemVendor {
path_regexp /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$
}
@denyUser {
path_regexp /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$
}
@denyroots {
path_regexp /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess)
}
respond @denytl 403
respond @denydangerousSystemVendor 403
respond @denyUser 403
respond @denyroots 403
}
### 5. Links to relevant resources:
I suspect its a problem with the php-fpm buffersize. I did try the various "new" caddy versions (9.0.1, and master) with the same results. If I restart php-fpm it sometimes makes it work for a while. Here are my listening ports:
tcp 0 0 127.0.0.1:2019 0.0.0.0:* LISTEN 25380/caddy
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2976/sshd [listener
tcp 0 0 127.0.0.1:5232 0.0.0.0:* LISTEN 2940/python3
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 18751/php-fpm.conf)
tcp 0 0 :::22 :::* LISTEN 2976/sshd [listener
tcp 0 0 :::80 :::* LISTEN 25380/caddy
tcp 0 0 :::443 :::* LISTEN 25380/caddy
udp 0 0 :::443 :::* 25380/caddy
And here are my firewall configs:
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
iifname "lo" accept comment "Accept any localhost traffic"
udp dport 443 accept
ct state { established, related } accept comment "Accept traffic originated from us"
tcp dport 443 accept
tcp dport 80 accept
ct state invalid drop comment "Drop invalid connections"
tcp dport 113 reject comment "Reject AUTH to make it fail fast"
ip protocol icmp icmp type { echo-reply, destination-unreachable, echo-request, time-exceeded, parameter-problem } accept comment "Accept ICMP"
ip6 nexthdr ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply } accept comment "Accept basic IPv6 functionality"
ip6 nexthdr ipv6-icmp ip6 hoplimit 255 icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept comment "Allow IPv6 SLAAC"
ip6 nexthdr ipv6-icmp icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, mld2-listener-report } ip6 saddr fe80::/10 accept comment "Allow IPv6 multicast listener discovery on link-local"
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
It should be noted that other websites work FINE, just the grav cms which seems unahppy.