Caddy not using http3

1. The problem I’m having:

Caddy does not enable http3 for my site but instead HTTP2. Initially, when I was working with the same example, HTTP3 was enabled.

2. Error messages and/or full log output:

3. Caddy version:

2.6.4

4. How I installed and ran Caddy:

Runs as a service

a. System environment:

cent os 7, systemd

b. Command:

caddy start

c. Service/unit/compose file:

d. My complete Caddy config:

my domain {
	respond "Protocol is {http.request.proto}"
	encode gzip
	reverse_proxy localhost:3000
	log {
		output file /var/log/caddy/one.log
	}

	# handle vs handle_path

	# handle /socket/* {
	#         reverse_proxy localhost:8081 # http://chat:8006/; 
	# }
	# handle_path /api/* {
	#         reverse_proxy localhost:8082
	#         # reverse_proxy http://apserver:3000/;
	# }
}

5. Links to relevant resources:

Use of HTTP/3 by browsers isn’t a guarantee. They first try connecting over TCP, and if that was fast enough, there’s no reason to try connecting over UDP.

You’d have to try using a client that only tries connecting with HTTP/3 to check. You can do that with a build of curl that includes --http3 support, but that might not be included in the build you have on your system.

You can use a docker image including curl with HTTP/3 to make a test request. Try this, with your domain instead:

$ docker run -it --rm ymuski/curl-http3 curl -vs -D/dev/stdout -o/dev/null --http3 https://caddyserver.com
*   Trying 165.227.20.207:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
*  subjectAltName: host "caddyserver.com" matched cert's "caddyserver.com"
* Connected to caddyserver.com (165.227.20.207) port 443 (#0)
* using HTTP/3
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: caddyserver.com]
* h2h3 [user-agent: curl/7.88.1-DEV]
* h2h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x5600c27ad920)
> GET / HTTP/3
> Host: caddyserver.com
> user-agent: curl/7.88.1-DEV
> accept: */*
> 
< HTTP/3 200 
HTTP/3 200 
< content-type: text/html; charset=utf-8
content-type: text/html; charset=utf-8
< content-length: 39108
content-length: 39108
< server: Caddy
server: Caddy

< 
{ [5281 bytes data]
* Connection #0 to host caddyserver.com left intact
1 Like

Okay. I will be using this method to check from now on.

But I want my site to only use http3

I also increase buffer size of my system according to this link. HTTP3 is enabled heree.
But my site still stays in http2.

Logs

2023/04/06 04:38:30.339 INFO    http    enabling HTTP/3 listener        {"addr": ":443"}
2023/04/06 04:38:30.340 INFO    failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size for details.

current sysctl values

net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.ipv4.tcp_rmem = 4096        87380   6291456
net.ipv4.udp_rmem_min = 4096

Okay, that’s a different question then.

You can use the servers global option to set protocols to only h3

{
	servers {
		protocols h3
	}
}

Keep in mind though that this might not really be viable in production because HTTP/3 client support is still somewhat low, and the ACME TLS-ALPN challenge probably wouldn’t work because I don’t think ACME issuers connect over HTTP/3 yet (I might be wrong about that, haven’t checked lately).

Yes. I have seen this solution. Also tried, my site was not loading when I forced it to use http3. Will check once again.

But I don’t know where can I verify if ACME issuers have support for Http3

Around 4-5 days back…the eg which I tried in caddy, was showing http3. The problem started when I changed my sysctl settings. I don’t know.

1 Like

I am getting this output. Just tried to run caddy as usual. haven’t seen this error before.

HTTP/3 requested for non-HTTPS URL

Make sure to use https:// in front of the URL.

My site still chooses http1.1. I dont know why. It is just a simple webpage.

* Connected to port 443 (#0)
* ALPN: offers http/1.1
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
{ [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):
{ [21 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [3856 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [79 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
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: CN=domain
*  start date: Mar 29 03:20:12 2023 GMT
*  expire date: Jun 27 03:20:11 2023 GMT
*  subjectAltName: host "domain" matched cert's "domain"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/1.1
} [5 bytes data]
> GET / HTTP/1.1
> Host: dev.test.kapil.chefgarden.asia
> User-Agent: curl/7.88.1-DEV
> Accept: */*
> 
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [130 bytes data]
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Access-Control-Allow-Headers: *
Access-Control-Allow-Headers: *
< Access-Control-Allow-Methods: *
Access-Control-Allow-Methods: *
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Alt-Svc: h3=":443"; ma=2592000
Alt-Svc: h3=":443"; ma=2592000
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< Date: Mon, 10 Apr 2023 13:40:11 GMT
Date: Mon, 10 Apr 2023 13:40:11 GMT
< Etag: W/"11ab-cPbqkVR6PVxxrHRjFeRLF0HXHjs"
Etag: W/"11ab-cPbqkVR6PVxxrHRjFeRLF0HXHjs"
< Referrer-Policy: no-referrer-when-downgrade
Referrer-Policy: no-referrer-when-downgrade
< Server: Caddy
Server: Caddy
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload;
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload;
< Vary: Accept-Encoding
Vary: Accept-Encoding
< X-Content-Type-Options: no sniff
X-Content-Type-Options: no sniff
< X-Frame-Options: DENY
X-Frame-Options: DENY
< X-Powered-By: Express
X-Powered-By: Express
< Transfer-Encoding: chunked
Transfer-Encoding: chunked

Unfortunately we’re unable to assist further if you redact the domain name (and the command you use to connect). :slightly_frowning_face: (See the forum rules and help template instructions)

@matt Okay. Got it.

My site still chooses http1.1. I dont know why. It is just a simple webpage.

docker run -it --rm ymuski/curl-http3 curl -vs -D/dev/stdout -o/dev/null --http3 https://dev.test.kapil.chefgarden.asia
*   Trying 109.123.247.255:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
*   Trying 109.123.247.255:443...
* Connected to dev.test.kapil.chefgarden.asia (109.123.247.255) port 443 (#0)
* ALPN: offers http/1.1
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
{ [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):
{ [21 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [3856 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [79 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
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: CN=dev.test.kapil.chefgarden.asia
*  start date: Mar 29 03:20:12 2023 GMT
*  expire date: Jun 27 03:20:11 2023 GMT
*  subjectAltName: host "dev.test.kapil.chefgarden.asia" matched cert's "dev.test.kapil.chefgarden.asia"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* using HTTP/1.1
} [5 bytes data]
> GET / HTTP/1.1
> Host: dev.test.kapil.chefgarden.asia
> User-Agent: curl/7.88.1-DEV
> Accept: */*
> 
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [130 bytes data]
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Access-Control-Allow-Headers: *
Access-Control-Allow-Headers: *
< Access-Control-Allow-Methods: *
Access-Control-Allow-Methods: *
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Alt-Svc: h3=":443"; ma=2592000
Alt-Svc: h3=":443"; ma=2592000
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8
< Date: Tue, 11 Apr 2023 03:37:44 GMT
Date: Tue, 11 Apr 2023 03:37:44 GMT
< Etag: W/"11ab-cPbqkVR6PVxxrHRjFeRLF0HXHjs"
Etag: W/"11ab-cPbqkVR6PVxxrHRjFeRLF0HXHjs"
< Referrer-Policy: no-referrer-when-downgrade
Referrer-Policy: no-referrer-when-downgrade
< Server: Caddy
Server: Caddy
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload;
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload;
< Vary: Accept-Encoding
Vary: Accept-Encoding
< X-Content-Type-Options: no sniff
X-Content-Type-Options: no sniff
< X-Frame-Options: DENY
X-Frame-Options: DENY
< X-Powered-By: Express
X-Powered-By: Express
< Transfer-Encoding: chunked
Transfer-Encoding: chunked

I see HTTP/3:

$ docker run -it --rm ymuski/curl-http3 curl -vs -D/dev/stdout -o/dev/null --http3 https://dev.test.kapil.chefgarden.asia 
*   Trying 109.123.247.255:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
*   Trying 109.123.247.255:443...
* Connected to dev.test.kapil.chefgarden.asia (109.123.247.255) port 443 (#0)
* ALPN: offers http/1.1
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
*  subjectAltName: host "dev.test.kapil.chefgarden.asia" matched cert's "dev.test.kapil.chefgarden.asia"
* Connected to dev.test.kapil.chefgarden.asia (109.123.247.255) port 443 (#0)
* using HTTP/3
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: dev.test.kapil.chefgarden.asia]
* h2h3 [user-agent: curl/7.88.1-DEV]
* h2h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x565150969930)
> GET / HTTP/3
> Host: dev.test.kapil.chefgarden.asia
> user-agent: curl/7.88.1-DEV
> accept: */*
> 
< HTTP/3 200 
HTTP/3 200 
< vary: Accept-Encoding
vary: Accept-Encoding
< date: Tue, 11 Apr 2023 13:59:14 GMT
date: Tue, 11 Apr 2023 13:59:14 GMT
< etag: W/"11ab-cPbqkVR6PVxxrHRjFeRLF0HXHjs"
etag: W/"11ab-cPbqkVR6PVxxrHRjFeRLF0HXHjs"
< server: Caddy
server: Caddy
< referrer-policy: no-referrer-when-downgrade
referrer-policy: no-referrer-when-downgrade
< content-type: text/html; charset=utf-8
content-type: text/html; charset=utf-8
< x-frame-options: DENY
x-frame-options: DENY
< access-control-allow-headers: *
access-control-allow-headers: *
< x-powered-by: Express
x-powered-by: Express
< strict-transport-security: max-age=31536000; includeSubdomains; preload;
strict-transport-security: max-age=31536000; includeSubdomains; preload;
< x-content-type-options: nosniff
x-content-type-options: nosniff
< accept-ranges: bytes
accept-ranges: bytes
< access-control-allow-origin: *
access-control-allow-origin: *
< access-control-allow-origin: *
access-control-allow-origin: *
< access-control-allow-methods: *
access-control-allow-methods: *

< 
{ [2415 bytes data]
* Connection #0 to host dev.test.kapil.chefgarden.asia left intact

Does your local machine/firewall block outgoing UDP traffic?

2 Likes

No…There is no issue with firewall/outgoing UDP.

Thanks for your response :+1:

Well, this is definitely a “works for me” situation. I don’t know what to tell you. I can even load your site with HTTP/3. So there’s no problem with Caddy, it’s a problem with your local machine not being able to make HTTP/3 requests to your server, somehow.

Could be a box in between you and your server blocking/dropping/degrading UDP packets. But it’s clearly working (for me too).

Another doubt I had…When I check in HTTP3check.net, I see that QUIC is not enabled. Is this an error? If yes, how can I correct it?

That website is not reliable. They only try an older draft revision of the QUIC protocol. We’ve reached out to them in the past to ask them to fix it, but they still haven’t yet.

2 Likes

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