1. The problem I’m having:
Struggling to get HTTP/3 to work for our domains. Curl reports “Weird server reply”:
$ curl -vL --http3 https://imusic.se/ > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Host imusic.se:443 was resolved.
* IPv6: (none)
* IPv4: 83.94.121.60
* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
* Trying 83.94.121.60:443...
* ALPN: curl offers h2,http/1.1
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* connect to 83.94.121.60 port 443 failed: Weird server reply
* Trying 83.94.121.60:443...
{ [5 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [15 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2067 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [78 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [36 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [36 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=imusic.se
* start date: Mar 19 11:31:03 2025 GMT
* expire date: Jun 17 11:31:02 2025 GMT
* subjectAltName: host "imusic.se" matched cert's "imusic.se"
* issuer: C=US; O=Let's Encrypt; CN=E6
* SSL certificate verify ok.
* Connected to imusic.se (83.94.121.60) port 443
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://imusic.se/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: imusic.se]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.12.1]
* [HTTP/2] [1] [accept: */*]
} [5 bytes data]
> GET / HTTP/2
> Host: imusic.se
> User-Agent: curl/8.12.1
> Accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [122 bytes data]
* Request completely sent off
{ [5 bytes data]
< HTTP/2 200
< alt-svc: h3=":443"; ma=2592000
< cache-control: must-revalidate, no-cache, private
< content-language: sv-SE
< content-type: text/html; charset=UTF-8
< date: Thu, 20 Mar 2025 08:55:35 GMT
< expires: Mon, 26 Jul 1997 05:00:00 GMT
< last-modified: Thu, 20 Mar 2025 08:55:35 GMT
< pragma: no-cache
< server: Caddy
< set-cookie: session=QrMuDSbjGElKnQtbOzXfKqmrlqebyHdGvjBH4png; path=/; domain=.imusic.se; secure; httponly; samesite=lax
< set-cookie: language=sv; path=/; domain=.imusic.se; secure; httponly; samesite=lax
< vary: Origin
< x-frame-options: SAMEORIGIN
Compare to another domain, which is still on Nginx and has HTTP/3 working:
$ curl -vL --http3 https://imusic.dk/ > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Host imusic.dk:443 was resolved.
* IPv6: (none)
* IPv4: 83.94.121.62
* Trying 83.94.121.62:443...
* Server certificate:
* subject: CN=imusic.dk
* start date: Feb 26 22:06:11 2025 GMT
* expire date: May 27 22:06:10 2025 GMT
* subjectAltName: host "imusic.dk" matched cert's "imusic.dk"
* issuer: C=US; O=Let's Encrypt; CN=R11
* SSL certificate verify ok.
* Connected to imusic.dk (83.94.121.62) port 443
* using HTTP/3
* [HTTP/3] [0] OPENED stream for https://imusic.dk/
* [HTTP/3] [0] [:method: GET]
* [HTTP/3] [0] [:scheme: https]
* [HTTP/3] [0] [:authority: imusic.dk]
* [HTTP/3] [0] [:path: /]
* [HTTP/3] [0] [user-agent: curl/8.12.1]
* [HTTP/3] [0] [accept: */*]
> GET / HTTP/3
> Host: imusic.dk
> User-Agent: curl/8.12.1
> Accept: */*
>
* Request completely sent off
< HTTP/3 200
< server: nginx/1.27.4
< content-type: text/html; charset=UTF-8
< expires: Mon, 26 Jul 1997 05:00:00 GMT
< cache-control: must-revalidate, no-cache, private
< last-modified: Thu, 20 Mar 2025 08:55:30 GMT
< pragma: no-cache
< content-language: da-DK
< date: Thu, 20 Mar 2025 08:55:30 GMT
< x-frame-options: SAMEORIGIN
< vary: Origin
< set-cookie: session=lef5q6fxE51m7NTrYwqdQIVRZ4O7kfgO897SiiIq; path=/; domain=.imusic.dk; secure; httponly; samesite=lax
< set-cookie: language=da; path=/; domain=.imusic.dk; secure; httponly; samesite=lax
< alt-svc: h3=":443"; ma=864000
< x-content-type-options: nosniff
<
2. Error messages and/or full log output:
Log output for the request with debug
enabled:
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.3384054,"logger":"events","msg":"event","name":"tls_get_certificate","id":"a1d08b8d-6425-4ddf-9289-7276ca41ada3","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4866,4867,49195,49199,49196,49200,52393,52392,49161,49171,49162,49172,156,157,47,53,10],"ServerName":"imusic.se","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771,770,769],"Conn":{}}}}
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.3384788,"logger":"tls.handshake","msg":"choosing certificate","identifier":"imusic.se","num_choices":1}
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.338498,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"imusic.se","subjects":["imusic.se"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"6286f65f89e0ee27ea867019b0f8fb8aeabb4e8b97718194ddeb6db5bffe7753"}
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.3385096,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"80.142.138.32","remote_port":"52986","subjects":["imusic.se"],"managed":true,"expiration":1750162246,"hash":"6286f65f89e0ee27ea867019b0f8fb8aeabb4e8b97718194ddeb6db5bffe7753"}
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.361729,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_ip":"80.142.138.32","remote_port":"52986","proto":"HTTP/2.0","method":"GET","host":"imusic.se","uri":"/","headers":{"User-Agent":["curl/8.12.1"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"imusic.se"}},"method":"GET","uri":"/index.php"}
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.3618112,"logger":"http.reverse_proxy.transport.fastcgi","msg":"roundtrip","request":{"remote_ip":"80.142.138.32","remote_port":"52986","proto":"HTTP/2.0","method":"GET","host":"imusic.se","uri":"/index.php","headers":{"User-Agent":["curl/8.12.1"],"Accept":["*/*"],"X-Forwarded-For":["80.142.138.32"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["imusic.se"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"imusic.se"}},"env":{"REMOTE_PORT":"52986","REQUEST_METHOD":"GET","SCRIPT_NAME":"/index.php","REMOTE_ADDR":"80.142.138.32","REMOTE_USER":"","HTTP_HOST":"imusic.se","REMOTE_IDENT":"","REQUEST_SCHEME":"https","HTTP_X_FORWARDED_FOR":"80.142.138.32","SCRIPT_FILENAME":"/srv/imusic/current/public/index.php","CONTENT_LENGTH":"","SERVER_NAME":"imusic.se","SERVER_SOFTWARE":"Caddy/2.6.2","DOCUMENT_URI":"/index.php","GATEWAY_INTERFACE":"CGI/1.1","CONTENT_TYPE":"","HTTP_USER_AGENT":"curl/8.12.1","HTTP_ACCEPT":"*/*","SSL_CIPHER":"TLS_AES_128_GCM_SHA256","REMOTE_HOST":"80.142.138.32","REQUEST_URI":"/","SERVER_PORT":"443","HTTPS":"on","AUTH_TYPE":"","QUERY_STRING":"","HTTP_X_FORWARDED_HOST":"imusic.se","HTTP_X_FORWARDED_PROTO":"https","PATH_INFO":"","SERVER_PROTOCOL":"HTTP/2.0","DOCUMENT_ROOT":"/srv/imusic/current/public","SSL_PROTOCOL":"TLSv1.3"},"dial":"/var/run/php/php-fpm.sock","env":{"CONTENT_LENGTH":"","SERVER_NAME":"imusic.se","SERVER_SOFTWARE":"Caddy/2.6.2","DOCUMENT_URI":"/index.php","SCRIPT_FILENAME":"/srv/imusic/current/public/index.php","GATEWAY_INTERFACE":"CGI/1.1","CONTENT_TYPE":"","HTTP_USER_AGENT":"curl/8.12.1","HTTP_ACCEPT":"*/*","REMOTE_HOST":"80.142.138.32","REQUEST_URI":"/","SERVER_PORT":"443","HTTPS":"on","SSL_CIPHER":"TLS_AES_128_GCM_SHA256","AUTH_TYPE":"","QUERY_STRING":"","HTTP_X_FORWARDED_HOST":"imusic.se","PATH_INFO":"","SERVER_PROTOCOL":"HTTP/2.0","DOCUMENT_ROOT":"/srv/imusic/current/public","SSL_PROTOCOL":"TLSv1.3","HTTP_X_FORWARDED_PROTO":"https","REMOTE_PORT":"52986","REQUEST_METHOD":"GET","SCRIPT_NAME":"/index.php","REMOTE_ADDR":"80.142.138.32","REMOTE_USER":"","HTTP_HOST":"imusic.se","REMOTE_IDENT":"","REQUEST_SCHEME":"https","HTTP_X_FORWARDED_FOR":"80.142.138.32"},"request":{"remote_ip":"80.142.138.32","remote_port":"52986","proto":"HTTP/2.0","method":"GET","host":"imusic.se","uri":"/index.php","headers":{"User-Agent":["curl/8.12.1"],"Accept":["*/*"],"X-Forwarded-For":["80.142.138.32"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["imusic.se"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"imusic.se"}}}
Mar 20 09:01:43 mach caddy[172843]: {"level":"debug","ts":1742461303.4416234,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"unix//var/run/php/php-fpm.sock","duration":0.079827919,"request":{"remote_ip":"80.142.138.32","remote_port":"52986","proto":"HTTP/2.0","method":"GET","host":"imusic.se","uri":"/index.php","headers":{"User-Agent":["curl/8.12.1"],"Accept":["*/*"],"X-Forwarded-For":["80.142.138.32"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["imusic.se"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"imusic.se"}},"headers":{"Expires":["Mon, 26 Jul 1997 05:00:00 GMT"],"Cache-Control":["must-revalidate, no-cache, private"],"Last-Modified":["Thu, 20 Mar 2025 09:01:43 GMT"],"Content-Type":["text/html; charset=UTF-8"],"Content-Language":["en-US"],"Pragma":["no-cache"],"Date":["Thu, 20 Mar 2025 09:01:43 GMT"],"X-Frame-Options":["SAMEORIGIN"],"Vary":["Origin"],"Set-Cookie":[]},"status":200}
I suspect this relates to Curl’s fallback HTTP/2 request, and not Curl’s aborted attempt to use HTTP/3.
3. Caddy version:
2.6.2
4. How I installed and ran Caddy:
a. System environment:
Ubuntu 24.04.2 LTS (x86_64
).
Caddy installed using packages:
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt install caddy
b. Command:
sudo 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 network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
d. My complete Caddy config:
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
{
email christian@imusic.dk
#default_sni imusic.dk
#debug
}
(imusic) {
root * /srv/imusic/current/public
encode
php_fastcgi unix//var/run/php/php-fpm.sock
file_server
log {
format console
output file /var/log/caddy/access.log
}
}
imusic.be {
import imusic
}
www.imusic.be {
redir https://imusic.be{uri}
}
imusic.br.com {
import imusic
}
www.imusic.br.com {
redir https://imusic.br.com{uri}
}
imusic.ca {
import imusic
}
www.imusic.ca {
redir https://imusic.ca{uri}
}
imusic.ch {
import imusic
}
www.imusic.ch {
redir https://imusic.ch{uri}
}
imusic.de {
import imusic
}
www.imusic.de {
redir https://imusic.de{uri}
}
imusic.es {
import imusic
}
www.imusic.es {
redir https://imusic.es{uri}
}
imusic.fi {
import imusic
}
www.imusic.fi {
redir https://imusic.fi{uri}
}
imusic.fr {
import imusic
}
www.imusic.fr {
redir https://imusic.fr{uri}
}
imusic.is {
import imusic
}
www.imusic.is {
redir https://imusic.is{uri}
}
imusic.jp {
import imusic
}
www.imusic.jp {
redir https://imusic.jp{uri}
}
imusic.lv {
import imusic
}
www.imusic.lv {
redir https://imusic.lv{uri}
}
imusic.nl {
import imusic
}
www.imusic.nl {
redir https://imusic.nl{uri}
}
imusic.no {
import imusic
}
www.imusic.no {
redir https://imusic.no{uri}
}
imusic.pl {
import imusic
}
www.imusic.pl {
redir https://imusic.pl{uri}
}
imusic.pt {
import imusic
}
www.imusic.pt {
redir https://imusic.pt{uri}
}
imusic.se {
import imusic
}
www.imusic.se {
redir https://imusic.se{uri}
}
imusic.si {
import imusic
}
www.imusic.si {
redir https://imusic.si{uri}
}
imusic.sk {
import imusic
}
www.imusic.sk {
redir https://imusic.sk{uri}
}
imusic.uk {
import imusic
}
www.imusic.uk {
redir https://imusic.uk{uri}
}