Getting "ERR_SSL_PROTOCOL_ERROR" most of the time

1. The problem I’m having:

I’m trying to get https for my local services. Trying with Uptime Kuma first.
I’m using Caddy for local SSL only. No outside access. No port forwarding.
I’m using the Cloudflare DNS Plugin to achieve this.

The problem is that pretty much 99% of the time, I can’t access it with https because the browser shows this error: ERR_SSL_PROTOCOL_ERROR

The weird part is that it always work from my phone but ONLY when I use the DuckDuckGo Browser. If I use Chrome, Brave or Firefox on my phone, I get the same error. Only DuckDuckGo works. I noticed there’s a different output on the logs when I visit from DuckDuckGo Browser. I thought it was my computer, so I tried from a Windows Sandbox but still get the same issue.

But wait, there’s more.
I used the exact same Dockerfile, compose.yml, .env and Caddyfile at a different location. Everything works fine. What could be causing this?

Here’s the curl -v output

curl -v https://www.homelab2025.com
*   Trying 10.0.0.123:443...
* Connected to www.homelab2025.com (10.0.0.123) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=*.homelab2025.com
*  start date: May 21 23:45:08 2025 GMT
*  expire date: Aug 19 23:45:07 2025 GMT
*  subjectAltName: host "www.homelab2025.com" matched cert's "*.homelab2025.com"
*  issuer: C=US; O=Let's Encrypt; CN=E6
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: www.homelab2025.com]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x56365ee757a0)
> GET / HTTP/2
> Host: www.homelab2025.com
> user-agent: curl/7.88.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
< content-type: text/plain; charset=utf-8
< date: Thu, 22 May 2025 01:37:24 GMT
< location: /status/service
< vary: Accept
< via: 1.1 Caddy
< x-frame-options: SAMEORIGIN
< content-length: 37
<
* Connection #0 to host www.homelab2025.com left intact
Found. Redirecting to /status/service

2. Error messages and/or full log output:

caddy  | {"level":"debug","ts":1747876793.2589161,"logger":"events","msg":"event","name":"tls_get_certificate","id":"6fd45a62-638f-4c95-bb7f-0419d6f1ab95","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"ServerName":"cloudflare-ech.com","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"10.0.0.10","Port":63917,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1747876793.259084,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"cloudflare-ech.com"}
caddy  | {"level":"debug","ts":1747876793.2590897,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.com"}
caddy  | {"level":"debug","ts":1747876793.2590928,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*"}
caddy  | {"level":"debug","ts":1747876793.2591012,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"10.0.0.10","remote_port":"63917","server_name":"cloudflare-ech.com","remote":"10.0.0.10:63917","identifier":"cloudflare-ech.com","cipher_suites":[4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"cert_cache_fill":0.0001,"load_or_obtain_if_necessary":true,"on_demand":false}
caddy  | {"level":"debug","ts":1747876793.259182,"logger":"http.stdlib","msg":"http: TLS handshake error from 10.0.0.10:63917: no certificate available for 'cloudflare-ech.com'"}
caddy  | {"level":"debug","ts":1747876793.2609184,"logger":"events","msg":"event","name":"tls_get_certificate","id":"5c8b604c-2f64-4813-aa24-937c3bdfd978","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"ServerName":"cloudflare-ech.com","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"10.0.0.10","Port":63918,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1747876793.260967,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"cloudflare-ech.com"}
caddy  | {"level":"debug","ts":1747876793.260988,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.com"}
caddy  | {"level":"debug","ts":1747876793.2609916,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*"}
caddy  | {"level":"debug","ts":1747876793.2609982,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"10.0.0.10","remote_port":"63918","server_name":"cloudflare-ech.com","remote":"10.0.0.10:63918","identifier":"cloudflare-ech.com","cipher_suites":[4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"cert_cache_fill":0.0001,"load_or_obtain_if_necessary":true,"on_demand":false}
caddy  | {"level":"debug","ts":1747876793.261033,"logger":"http.stdlib","msg":"http: TLS handshake error from 10.0.0.10:63918: no certificate available for 'cloudflare-ech.com'"}



#It works when I visit the website from DuckDuckGo Browser on Android. Check the difference after this.



caddy  | {"level":"debug","ts":1747876799.5392537,"logger":"events","msg":"event","name":"tls_get_certificate","id":"47eebda1-3af8-449c-9450-5df3d4f40fb6","origin":"tls","data":{"client_hello":{"CipherSuites":[19018,4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"ServerName":"www.homelab2025.com","SupportedCurves":[64250,4588,29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[56026,772,771],"RemoteAddr":{"IP":"10.0.0.60","Port":45254,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1747876799.5392992,"logger":"tls.handshake","msg":"choosing certificate","identifier":"www.homelab2025.com","num_choices":1}
caddy  | {"level":"debug","ts":1747876799.5393062,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"www.homelab2025.com","subjects":["www.homelab2025.com"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"f0a91dc4bce08c8d090fc4deac2ee5f431196e7712afc437ad6b2e1e034e15d3"}
caddy  | {"level":"debug","ts":1747876799.5393128,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"10.0.0.60","remote_port":"45254","subjects":["www.homelab2025.com"],"managed":true,"expiration":1755649266,"hash":"f0a91dc4bce08c8d090fc4deac2ee5f431196e7712afc437ad6b2e1e034e15d3"}
caddy  | {"level":"debug","ts":1747876799.5812647,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876799.5878925,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.006561258,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/","headers":{"Sec-Gpc":["1"],"Sec-Fetch-Mode":["navigate"],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"Sec-Ch-Ua-Platform":["\"Android\""],"X-Forwarded-Host":["www.homelab2025.com"],"Via":["2.0 Caddy"],"Sec-Fetch-User":["?1"],"X-Requested-With":["com.duckduckgo.mobile.android"],"Priority":["u=0, i"],"Upgrade-Insecure-Requests":["1"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Accept-Language":["en-US,en;q=0.9"],"Sec-Ch-Ua-Mobile":["?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"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"X-Forwarded-Proto":["https"],"Sec-Fetch-Site":["none"],"Sec-Fetch-Dest":["document"],"X-Forwarded-For":["10.0.0.60"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"Vary":["Accept"],"Content-Type":["text/html; charset=utf-8"],"Content-Length":["44"],"Date":["Thu, 22 May 2025 01:19:59 GMT"],"Connection":["keep-alive"],"Keep-Alive":["timeout=5"],"X-Frame-Options":["SAMEORIGIN"],"Location":["/status/service"]},"status":302}
caddy  | {"level":"debug","ts":1747876799.6432235,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876799.6449149,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.001629564,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/status/service","headers":{"Sec-Ch-Ua-Platform":["\"Android\""],"X-Forwarded-Proto":["https"],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Accept-Language":["en-US,en;q=0.9"],"Priority":["u=0, i"],"Sec-Fetch-Mode":["navigate"],"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"],"Sec-Ch-Ua-Mobile":["?1"],"X-Requested-With":["com.duckduckgo.mobile.android"],"X-Forwarded-For":["10.0.0.60"],"X-Forwarded-Host":["www.homelab2025.com"],"Via":["2.0 Caddy"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"Sec-Fetch-Dest":["document"],"Upgrade-Insecure-Requests":["1"],"Sec-Gpc":["1"],"Accept-Encoding":["gzip, deflate, br, zstd"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"Date":["Thu, 22 May 2025 01:19:59 GMT"],"Connection":["keep-alive"],"Keep-Alive":["timeout=5"],"X-Frame-Options":["SAMEORIGIN"],"Content-Type":["text/html; charset=utf-8"],"Content-Length":["3532"],"Etag":["W/\"dcc-dtutMLt7hO3XVkgTaU35mFugAhs\""]},"status":200}
caddy  | {"level":"debug","ts":1747876799.7369206,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876799.7376168,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876799.742394,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.005367916,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/assets/index-bOVKKa1O.css","headers":{"Sec-Fetch-Dest":["style"],"Accept-Language":["en-US,en;q=0.9"],"Origin":["https://www.homelab2025.com"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"X-Requested-With":["com.duckduckgo.mobile.android"],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"X-Forwarded-For":["10.0.0.60"],"Via":["2.0 Caddy"],"Sec-Fetch-Site":["same-origin"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Sec-Ch-Ua-Platform":["\"Android\""],"Sec-Fetch-Mode":["cors"],"X-Forwarded-Host":["www.homelab2025.com"],"Sec-Ch-Ua-Mobile":["?1"],"Accept":["text/css,*/*;q=0.1"],"Referer":["https://www.homelab2025.com/status/service"],"Priority":["u=0"],"X-Forwarded-Proto":["https"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"Vary":["Accept-Encoding"],"Accept-Ranges":["bytes"],"Etag":["W/\"afc3-193e2ecf7a8\""],"Connection":["keep-alive"],"Keep-Alive":["timeout=5"],"X-Frame-Options":["SAMEORIGIN"],"Content-Encoding":["gzip"],"Content-Type":["text/css; charset=UTF-8"],"Cache-Control":["public, max-age=0"],"Last-Modified":["Fri, 20 Dec 2024 07:16:41 GMT"],"Content-Length":["44995"],"Date":["Thu, 22 May 2025 01:19:59 GMT"]},"status":200}
caddy  | {"level":"debug","ts":1747876799.74436,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.006616487,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/assets/index-B_z9mVlf.js","headers":{"Sec-Fetch-Site":["same-origin"],"Origin":["https://www.homelab2025.com"],"X-Requested-With":["com.duckduckgo.mobile.android"],"Priority":["u=1"],"Via":["2.0 Caddy"],"Accept":["*/*"],"Accept-Language":["en-US,en;q=0.9"],"Sec-Ch-Ua-Platform":["\"Android\""],"X-Forwarded-For":["10.0.0.60"],"Sec-Fetch-Mode":["cors"],"Sec-Fetch-Dest":["script"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"X-Forwarded-Host":["www.homelab2025.com"],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"Sec-Ch-Ua-Mobile":["?1"],"Referer":["https://www.homelab2025.com/status/service"],"Accept-Encoding":["gzip, deflate, br, zstd"],"X-Forwarded-Proto":["https"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"Content-Type":["application/javascript; charset=UTF-8"],"Accept-Ranges":["bytes"],"Cache-Control":["public, max-age=0"],"Last-Modified":["Fri, 20 Dec 2024 07:16:41 GMT"],"Content-Length":["489902"],"Connection":["keep-alive"],"Vary":["Accept-Encoding"],"Content-Encoding":["gzip"],"Etag":["W/\"779ae-193e2ecf7a8\""],"Date":["Thu, 22 May 2025 01:19:59 GMT"],"Keep-Alive":["timeout=5"],"X-Frame-Options":["SAMEORIGIN"]},"status":200}
caddy  | {"level":"debug","ts":1747876799.9775877,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876799.9775877,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876799.981267,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.003599161,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/icon.svg","headers":{"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"Referer":["https://www.homelab2025.com/status/service"],"Accept-Language":["en-US,en;q=0.9"],"Priority":["i"],"Origin":["https://www.homelab2025.com"],"Sec-Ch-Ua-Platform":["\"Android\""],"X-Forwarded-For":["10.0.0.60"],"Sec-Ch-Ua-Mobile":["?1"],"X-Requested-With":["com.duckduckgo.mobile.android"],"Sec-Fetch-Site":["same-origin"],"Sec-Fetch-Dest":["image"],"Accept-Encoding":["gzip, deflate, br, zstd"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["www.homelab2025.com"],"Via":["2.0 Caddy"],"Sec-Fetch-Mode":["cors"],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"Accept":["image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"Last-Modified":["Fri, 20 Dec 2024 07:16:41 GMT"],"Content-Length":["617"],"Keep-Alive":["timeout=5"],"Content-Encoding":["gzip"],"Content-Type":["image/svg+xml"],"Accept-Ranges":["bytes"],"Etag":["W/\"269-193e2ecf7a8\""],"Date":["Thu, 22 May 2025 01:19:59 GMT"],"Connection":["keep-alive"],"X-Frame-Options":["SAMEORIGIN"],"Vary":["Accept-Encoding"],"Cache-Control":["public, max-age=0"]},"status":200}
caddy  | {"level":"debug","ts":1747876800.0208743,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"10.0.0.123:3001","total_upstreams":1}
caddy  | {"level":"debug","ts":1747876800.0232003,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.002235749,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/icon.svg","headers":{"X-Forwarded-For":["10.0.0.60"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"X-Requested-With":["com.duckduckgo.mobile.android"],"Accept-Language":["en-US,en;q=0.9"],"X-Forwarded-Host":["www.homelab2025.com"],"Via":["2.0 Caddy"],"If-None-Match":["W/\"269-193e2ecf7a8\""],"Priority":["i"],"If-Modified-Since":["Fri, 20 Dec 2024 07:16:41 GMT"],"X-Forwarded-Proto":["https"],"Accept":["image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"],"Referer":["https://www.homelab2025.com/status/service"],"Sec-Fetch-Mode":["no-cors"],"Sec-Ch-Ua-Platform":["\"Android\""],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"Sec-Fetch-Site":["same-origin"],"Sec-Fetch-Dest":["image"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Sec-Ch-Ua-Mobile":["?1"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"X-Frame-Options":["SAMEORIGIN"],"Last-Modified":["Fri, 20 Dec 2024 07:16:41 GMT"],"Etag":["W/\"269-193e2ecf7a8\""],"Date":["Thu, 22 May 2025 01:20:00 GMT"],"Vary":["Accept-Encoding"],"Accept-Ranges":["bytes"],"Cache-Control":["public, max-age=0"],"Connection":["keep-alive"],"Keep-Alive":["timeout=5"]},"status":304}
caddy  | {"level":"debug","ts":1747876800.0455482,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"10.0.0.123:3001","duration":0.067773526,"request":{"remote_ip":"10.0.0.60","remote_port":"45254","client_ip":"10.0.0.60","proto":"HTTP/2.0","method":"GET","host":"www.homelab2025.com","uri":"/api/status-page/heartbeat/service","headers":{"X-Requested-With":["com.duckduckgo.mobile.android"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Priority":["u=1, i"],"X-Forwarded-For":["10.0.0.60"],"Via":["2.0 Caddy"],"Sec-Ch-Ua-Platform":["\"Android\""],"Accept":["application/json, text/plain, */*"],"Sec-Fetch-Site":["same-origin"],"Sec-Fetch-Dest":["empty"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["www.homelab2025.com"],"Sec-Ch-Ua-Mobile":["?1"],"Sec-Ch-Ua":["\"Chromium\";v=\"136\", \"DuckDuckGo\";v=\"136\", \"Not.A/Brand\";v=\"99\""],"Accept-Language":["en-US,en;q=0.9"],"User-Agent":["Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"],"Sec-Fetch-Mode":["cors"],"Referer":["https://www.homelab2025.com/status/service"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"www.homelab2025.com"}},"headers":{"Connection":["keep-alive"],"Keep-Alive":["timeout=5"],"X-Frame-Options":["SAMEORIGIN"],"Cache-Control":["no-cache"],"Content-Type":["application/json; charset=utf-8"],"Content-Length":["36091"],"Etag":["W/\"8cfb-8MkkhVDfYDGhuQPcHiLTRCcasJw\""],"Date":["Thu, 22 May 2025 01:20:00 GMT"]},"status":200}
caddy  | {"level":"debug","ts":1747876800.2155852,"logger":"events","msg":"event","name":"tls_get_certificate","id":"c51d50e4-d280-42d9-aeed-eb1a9d6dadf2","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4866,4867,49195,49196,52393,49199,49200,52392,49171,49172,156,157,47,53],"ServerName":"homelab2025.com","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"10.0.0.60","Port":45262,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1747876800.2156265,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"homelab2025.com"}
caddy  | {"level":"debug","ts":1747876800.2156327,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.org"}
caddy  | {"level":"debug","ts":1747876800.2156358,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*"}
caddy  | {"level":"debug","ts":1747876800.2156441,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"10.0.0.60","remote_port":"45262","server_name":"homelab2025.com","remote":"10.0.0.60:45262","identifier":"homelab2025.com","cipher_suites":[4865,4866,4867,49195,49196,52393,49199,49200,52392,49171,49172,156,157,47,53],"cert_cache_fill":0.0001,"load_or_obtain_if_necessary":true,"on_demand":false}
caddy  | {"level":"debug","ts":1747876800.2157462,"logger":"http.stdlib","msg":"http: TLS handshake error from 10.0.0.60:45262: no certificate available for 'homelab2025.com'"}
caddy  | {"level":"debug","ts":1747876800.2466135,"logger":"events","msg":"event","name":"tls_get_certificate","id":"ee3cfd5d-8704-4c9d-b0c3-95679c10c393","origin":"tls","data":{"client_hello":{"CipherSuites":[4865,4866,4867,49195,49196,52393,49199,49200,52392,49171,49172,156,157,47,53],"ServerName":"homelab2025.com","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537,513],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"10.0.0.60","Port":45276,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1747876800.2466571,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"homelab2025.com"}
caddy  | {"level":"debug","ts":1747876800.2466629,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.org"}
caddy  | {"level":"debug","ts":1747876800.2466662,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*"}
caddy  | {"level":"debug","ts":1747876800.246674,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"10.0.0.60","remote_port":"45276","server_name":"homelab2025.com","remote":"10.0.0.60:45276","identifier":"homelab2025.com","cipher_suites":[4865,4866,4867,49195,49196,52393,49199,49200,52392,49171,49172,156,157,47,53],"cert_cache_fill":0.0001,"load_or_obtain_if_necessary":true,"on_demand":false}
caddy  | {"level":"debug","ts":1747876800.2467585,"logger":"http.stdlib","msg":"http: TLS handshake error from 10.0.0.60:45276: no certificate available for 'homelab2025.com'"}






3. Caddy version:

v2.10.0

4. How I installed and ran Caddy:

I used the xcaddy builder and Docker Compose.
Here’s my Dockerfile:

FROM caddy:builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/cloudflare

FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

a. System environment:

Debian 12.11 - x64
Docker 28.1.1

b. Command:

docker compose up -d

c. Service/unit/compose file:

services:
  caddy:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: caddy
    restart: unless-stopped
    env_file:
      - .env
    environment:
      - TZ=America/New_York
      - CLOUDFLARE_API_TOKEN=${CF_API_TOKEN}
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./caddy-config:/config
      - ./caddy-data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile

volumes:
  caddy-data:
  caddy-config:

d. My complete Caddy config:

{
        debug
}



# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.

:80 {
	# Set this path to your site's directory.
	root * /usr/share/caddy

	# Enable the static file server.
	file_server

	# Another common task is to set up a reverse proxy:
	# reverse_proxy localhost:8080

	# Or serve a PHP site through php-fpm:
	# php_fastcgi localhost:9000
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile



# ==========================================================================

www.homelab2025.com {

        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }

        reverse_proxy http://10.0.0.123:3001

}

# ==========================================================================

homelab2025.com {

        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }

        reverse_proxy http://10.0.0.123:3001

}

# ==========================================================================

5. Links to relevant resources:

Remove the HTTPS dns record from cloudflare. The browser is attempting an encrypted SNI connection, yet you haven’t specified any ECN parameters within the config, so caddy is not aware of this.

Only browsers not implementing this privacy standard (such as duck duck go and curl) can connect

Thanks for the reply.

I deleted it. Same issue.

I changed the Caddy file to this:

{
        debug
        dns cloudflare {env.CF_API_TOKEN}
        ech ech.homelab2025.com
}

www.homelab2025.com {

        reverse_proxy http://10.0.0.123:3001

}


*.homelab2025.com {

        reverse_proxy http://10.0.0.123:3001

}

Why is it that this exact same Caddyfile, without changing anything works on two different locations? Same domain name. Same router. Same ISP. Same browsers.
I have the exact same network infrastructure at my brothers and at my parents and they work just fine. It’s really odd.

{
        debug
        dns cloudflare {env.CF_API_TOKEN}
        ech ech.homelab2025.com
}

www.homelab2025.com {

        reverse_proxy http://10.0.0.123:3001

}


*.homelab2025.com {

        reverse_proxy http://10.0.0.123:3001

}

I tried this.
It didn’t work.

Looks like the issue is related to Encrypted Client Hello (ECH) but I don’t know how to fix this.

I created the ech.homelab2025.com subdomain in Cloudflare pointing back to the internal Caddy ip address. When I used the Caddyfile configuration above, Caddy automatically created a HTTPS DNS record on Cloudflare but even after that, I still get the SSL error.

Can anyone help?

That is interesting; here is a list of issued certificates crt.sh | homelab2025.com
and the one you showed has yet to be found by https://crt.sh after nearly 3 days.

I’ll try with a different domain when I get home.

Hi @Darknicks,

Other interesting finds

Here is not showing an entry for www.homelab2025.com DNS Spy report for homelab2025.com

And using curl I see Server: Apache, is that expected?

$ curl -Ii http://homelab2025.com
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 605912
Connection: keep-alive
X-WS-RateLimit-Limit: 1000
X-WS-RateLimit-Remaining: 999
Date: Sat, 24 May 2025 19:25:12 GMT
Server: Apache

And for Port 443 with HTTP not HTTPS I see Server: nginx

$ curl -Ii http://homelab2025.com:443
HTTP/1.1 400 Bad Request
Server: nginx
Date: Sat, 24 May 2025 19:28:03 GMT
Content-Type: text/html
Content-Length: 248
Connection: close

Port 443 with HTTPS

$ curl -k -Ii https://homelab2025.com:443
curl: (35) OpenSSL/3.0.13: error:0A000438:SSL routines::tlsv1 alert internal error

(post deleted by author)

1. The problem I’m having:

Alright, I started over with a different Domain name.
First of all, be aware that there is no port forwarding.
These services are only supposed to be available internally.
I’m using Caddy with Cloudflare’s DNS challange plugin.

Encrypted Client Hello (ECH) is what is failing here.

When I start Caddy, it sucessfully creates the HTTPS records on Cloudflare.
So it looks like that part is working fine. But still ECH is failing.

I don’t want to turn off ECH, even though I know that’s a solution.
Unless I’m missing something about ECH… Is it supposed to only work for externally accesible domains?

Here’s the curl -v output:

curl -v www.SelfHosted.pp.ua

*   Trying 192.168.0.15:80...
* Connected to www.SelfHosted.pp.ua (192.168.0.15) port 80 (#0)
> GET / HTTP/1.1
> Host: www.SelfHosted.pp.ua
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://www.SelfHosted.pp.ua/
< Server: Caddy
< Date: Sun, 25 May 2025 17:22:12 GMT
< Content-Length: 0
<
* Closing connection 0cl

curl -v SelfHosted.pp.ua

*   Trying 192.168.0.15:80...
* Connected to SelfHosted.pp.ua (192.168.0.15) port 80 (#0)
> GET / HTTP/1.1
> Host: SelfHosted.pp.ua
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://SelfHosted.pp.ua/
< Server: Caddy
< Date: Sun, 25 May 2025 17:22:29 GMT
< Content-Length: 0
<
* Closing connection 0

curl -v https://www.SelfHosted.pp.ua

*   Trying 192.168.0.15:443...
* Connected to www.SelfHosted.pp.ua (192.168.0.15) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=*.selfhosted.pp.ua
*  start date: May 25 02:01:43 2025 GMT
*  expire date: Aug 23 02:01:42 2025 GMT
*  subjectAltName: host "www.SelfHosted.pp.ua" matched cert's "*.selfhosted.pp.ua"
*  issuer: C=US; O=Let's Encrypt; CN=E6
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: www.SelfHosted.pp.ua]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x55a51e82e7a0)
> GET / HTTP/2
> Host: www.SelfHosted.pp.ua
> user-agent: curl/7.88.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
< content-type: text/plain; charset=utf-8
< date: Sun, 25 May 2025 17:23:04 GMT
< location: /status/services
< vary: Accept
< via: 1.1 Caddy
< x-frame-options: SAMEORIGIN
< content-length: 37
<
* Connection #0 to host www.SelfHosted.pp.ua left intact


curl -v https://SelfHosted.pp.ua

*   Trying 192.168.0.15:443...
* Connected to SelfHosted.pp.ua (192.168.0.15) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_CHACHA20_POLY1305_SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=selfhosted.pp.ua
*  start date: May 25 02:01:47 2025 GMT
*  expire date: Aug 23 02:01:46 2025 GMT
*  subjectAltName: host "SelfHosted.pp.ua" matched cert's "selfhosted.pp.ua"
*  issuer: C=US; O=Let's Encrypt; CN=E6
*  SSL certificate verify ok.
* using HTTP/2
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: SelfHosted.pp.ua]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x558bbc87d7a0)
> GET / HTTP/2
> Host: SelfHosted.pp.ua
> user-agent: curl/7.88.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
< content-type: text/plain; charset=utf-8
< date: Sun, 25 May 2025 17:23:47 GMT
< location: /status/services
< vary: Accept
< via: 1.1 Caddy
< x-frame-options: SAMEORIGIN
< content-length: 37
<
* Connection #0 to host SelfHosted.pp.ua left intact


When I visit the site from Chrome, Firefox and Edge, sometimes it goes through, but 99% of the time it fails and results in this error: ERR_SSL_PROTOCOL_ERROR

2. Error messages and/or full log output:


caddy  | {"level":"info","ts":1748193304.3745239,"msg":"maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined"}
caddy  | {"level":"info","ts":1748193304.3746724,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":7493758156,"previous":9223372036854775807}
caddy  | {"level":"info","ts":1748193304.3747456,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
caddy  | {"level":"info","ts":1748193304.3759706,"msg":"adapted config to JSON","adapter":"caddyfile"}
caddy  | {"level":"warn","ts":1748193304.3760104,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":10}
caddy  | {"level":"info","ts":1748193304.3768759,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
caddy  | {"level":"info","ts":1748193304.3771596,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000138c80"}
caddy  | {"level":"debug","ts":1748193304.4226127,"logger":"tls.ech","msg":"generated new ECH config","public_name":"ech.selfhosted.pp.ua","id":131}
caddy  | {"level":"info","ts":1748193304.4249513,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy  | {"level":"info","ts":1748193304.42506,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy  | {"level":"debug","ts":1748193304.425129,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["www.selfhosted.pp.ua","yt.selfhosted.pp.ua","selfhosted.pp.ua","*.selfhosted.pp.ua"]},{"subjects":["ech.SelfHosted.pp.ua"]},{}]},"encrypted_client_hello":{"configs":[{"public_name":"ech.SelfHosted.pp.ua"}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.50:3001"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.50:3000"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.50:3001"}]}]}]}],"terminal":true},{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.0.50:3001"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
caddy  | {"level":"debug","ts":1748193304.425642,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":false}
caddy  | {"level":"info","ts":1748193304.4256914,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy  | {"level":"info","ts":1748193304.4258146,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
caddy  | {"level":"info","ts":1748193304.4259522,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy  | {"level":"debug","ts":1748193304.42615,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
caddy  | {"level":"warn","ts":1748193304.4262114,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy  | {"level":"warn","ts":1748193304.4262323,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy  | {"level":"info","ts":1748193304.426251,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy  | {"level":"info","ts":1748193304.426301,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["www.selfhosted.pp.ua","yt.selfhosted.pp.ua","selfhosted.pp.ua","*.selfhosted.pp.ua"]}
caddy  | {"level":"warn","ts":1748193304.4266412,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [selfhosted.pp.ua]: no OCSP server specified in certificate","identifiers":["selfhosted.pp.ua"]}
caddy  | {"level":"debug","ts":1748193304.42673,"logger":"tls.cache","msg":"added certificate to cache","subjects":["selfhosted.pp.ua"],"expiration":1755914507,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"341bf291c7690f98c099c1580d338dedd14ed1d9165f5f431c4f3519c0273e8a","cache_size":1,"cache_capacity":10000}
caddy  | {"level":"debug","ts":1748193304.4267805,"logger":"events","msg":"event","name":"cached_managed_cert","id":"b3d46d8d-06e9-4771-b882-9d7e0ff80969","origin":"tls","data":{"sans":["selfhosted.pp.ua"]}}
caddy  | {"level":"warn","ts":1748193304.4271464,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [*.selfhosted.pp.ua]: no OCSP server specified in certificate","identifiers":["*.selfhosted.pp.ua"]}
caddy  | {"level":"debug","ts":1748193304.4272,"logger":"tls.cache","msg":"added certificate to cache","subjects":["*.selfhosted.pp.ua"],"expiration":1755914503,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"4bcaf06663bca5c003e07abd20a99bdcf72b47eb8950928c06083340caf2467d","cache_size":2,"cache_capacity":10000}
caddy  | {"level":"debug","ts":1748193304.4272316,"logger":"events","msg":"event","name":"cached_managed_cert","id":"d40aa68b-dafb-4da2-b5c5-0182dfd52d76","origin":"tls","data":{"sans":["*.selfhosted.pp.ua"]}}
caddy  | {"level":"warn","ts":1748193304.4275224,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [ech.selfhosted.pp.ua]: no OCSP server specified in certificate","identifiers":["ech.selfhosted.pp.ua"]}
caddy  | {"level":"debug","ts":1748193304.427601,"logger":"tls.cache","msg":"added certificate to cache","subjects":["ech.selfhosted.pp.ua"],"expiration":1755914503,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"2a0b71a34009dfc38b35f77fb4f88bfc8759ff09e1d89ee3049358962e17e3d4","cache_size":3,"cache_capacity":10000}
caddy  | {"level":"debug","ts":1748193304.427645,"logger":"events","msg":"event","name":"cached_managed_cert","id":"87f04afe-ac42-4c32-9d70-fb1df2915e15","origin":"tls","data":{"sans":["ech.selfhosted.pp.ua"]}}
caddy  | {"level":"debug","ts":1748193304.4277093,"logger":"events","msg":"event","name":"started","id":"3b381260-2d52-42fd-a3e3-f4d45713c498","origin":"","data":null}
caddy  | {"level":"info","ts":1748193304.4286346,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy  | {"level":"info","ts":1748193304.428686,"msg":"serving initial configuration"}
caddy  | {"level":"debug","ts":1748193304.439168,"logger":"tls.ech","msg":"publishing ECH config list","domains":["www.selfhosted.pp.ua","yt.selfhosted.pp.ua","selfhosted.pp.ua","*.selfhosted.pp.ua"],"config_ids":[131]}
caddy  | {"level":"debug","ts":1748193304.4402435,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 31038\n;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;www.selfhosted.pp.ua.\tIN\t SOA\n\n;; AUTHORITY SECTION:\nselfhosted.pp.ua.\t1094\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"debug","ts":1748193304.440983,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 44449\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;selfhosted.pp.ua.\tIN\t SOA\n\n;; ANSWER SECTION:\nselfhosted.pp.ua.\t1094\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"info","ts":1748193304.4774373,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"aae20edd-ca84-4b58-af5a-fccb411b6a18","try_again":1748279704.4774346,"try_again_in":86399.999999555}
caddy  | {"level":"info","ts":1748193304.4776158,"logger":"tls","msg":"finished cleaning storage units"}
caddy  | {"level":"debug","ts":1748193305.9060032,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 14287\n;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;yt.selfhosted.pp.ua.\tIN\t SOA\n\n;; AUTHORITY SECTION:\nselfhosted.pp.ua.\t1093\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"debug","ts":1748193305.9070034,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 19100\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;selfhosted.pp.ua.\tIN\t SOA\n\n;; ANSWER SECTION:\nselfhosted.pp.ua.\t1093\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"debug","ts":1748193307.0978634,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 39940\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;selfhosted.pp.ua.\tIN\t SOA\n\n;; ANSWER SECTION:\nselfhosted.pp.ua.\t1091\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"debug","ts":1748193308.4273028,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 46285\n;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;*.selfhosted.pp.ua.\tIN\t SOA\n\n;; AUTHORITY SECTION:\nselfhosted.pp.ua.\t1090\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"debug","ts":1748193308.4294531,"logger":"tls.soa_lookup","msg":"fetched SOA","msg":";; opcode: QUERY, status: NOERROR, id: 17499\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags:; udp: 1232\n\n;; QUESTION SECTION:\n;selfhosted.pp.ua.\tIN\t SOA\n\n;; ANSWER SECTION:\nselfhosted.pp.ua.\t1090\tIN\tSOA\thoward.ns.cloudflare.com. dns.cloudflare.com. 2373640417 10000 2400 604800 1800\n"}
caddy  | {"level":"info","ts":1748193308.972385,"logger":"tls","msg":"published ECH configuration list","domains":["www.selfhosted.pp.ua","yt.selfhosted.pp.ua","selfhosted.pp.ua","*.selfhosted.pp.ua"],"config_ids":[131]}
caddy  | {"level":"debug","ts":1748193326.1701038,"logger":"events","msg":"event","name":"tls_get_certificate","id":"432ad294-142b-4582-82c2-b14cbf40f89f","origin":"tls","data":{"client_hello":{"CipherSuites":[10794,4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"ServerName":"cloudflare-ech.com","SupportedCurves":[56026,4588,29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[31354,772,771],"RemoteAddr":{"IP":"192.168.0.60","Port":47040,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1748193326.1701834,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"cloudflare-ech.com"}
caddy  | {"level":"debug","ts":1748193326.1701896,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.com"}
caddy  | {"level":"debug","ts":1748193326.170193,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*"}
caddy  | {"level":"debug","ts":1748193326.1702318,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"192.168.0.60","remote_port":"47040","server_name":"cloudflare-ech.com","remote":"192.168.0.60:47040","identifier":"cloudflare-ech.com","cipher_suites":[10794,4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"cert_cache_fill":0.0003,"load_or_obtain_if_necessary":true,"on_demand":false}
caddy  | {"level":"debug","ts":1748193326.170298,"logger":"http.stdlib","msg":"http: TLS handshake error from 192.168.0.60:47040: no certificate available for 'cloudflare-ech.com'"}
caddy  | {"level":"debug","ts":1748193326.194233,"logger":"events","msg":"event","name":"tls_get_certificate","id":"1b1a774c-0804-4d8b-88d8-073491a93244","origin":"tls","data":{"client_hello":{"CipherSuites":[35466,4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"ServerName":"cloudflare-ech.com","SupportedCurves":[51914,4588,29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1027,2052,1025,1283,2053,1281,2054,1537],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[39578,772,771],"RemoteAddr":{"IP":"192.168.0.60","Port":47050,"Zone":""},"LocalAddr":{"IP":"172.18.0.2","Port":443,"Zone":""}}}}
caddy  | {"level":"debug","ts":1748193326.1942956,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"cloudflare-ech.com"}
caddy  | {"level":"debug","ts":1748193326.194304,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.com"}
caddy  | {"level":"debug","ts":1748193326.1943078,"logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"*.*"}
caddy  | {"level":"debug","ts":1748193326.1943197,"logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"192.168.0.60","remote_port":"47050","server_name":"cloudflare-ech.com","remote":"192.168.0.60:47050","identifier":"cloudflare-ech.com","cipher_suites":[35466,4865,4866,4867,49195,49199,49196,49200,52393,52392,49171,49172,156,157,47,53],"cert_cache_fill":0.0003,"load_or_obtain_if_necessary":true,"on_demand":false}
caddy  | {"level":"debug","ts":1748193326.1944108,"logger":"http.stdlib","msg":"http: TLS handshake error from 192.168.0.60:47050: no certificate available for 'cloudflare-ech.com'"}

3. Caddy version:

v2.10.0

4. How I installed and ran Caddy:

I used the xcaddy builder and Docker Compose.
Here’s my Dockerfile:

FROM caddy:builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/cloudflare

FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

a. System environment:

Debian 12.11 - x64
Docker 28.1.1

b. Command:

docker compose up -d

c. Service/unit/compose file:

services:
  caddy:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: caddy
    restart: unless-stopped
    env_file:
      - .env
    environment:
      - TZ=America/New_York
      - CLOUDFLARE_API_TOKEN=${CF_API_TOKEN}
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./caddy-config:/config
      - ./caddy-data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile

volumes:
  caddy-data:
  caddy-config:

d. My complete Caddy config:


{
        debug
        dns cloudflare {env.CF_API_TOKEN}
        ech ech.SelfHosted.pp.ua
}

#============================================================

SelfHosted.pp.ua {

        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }
        reverse_proxy http://192.168.0.50:3001
}

*.SelfHosted.pp.ua {
        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }
        reverse_proxy http://192.168.0.50:3001
}

www.SelfHosted.pp.ua {
        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }
        reverse_proxy http://192.168.0.50:3001
}

YT.SelfHosted.pp.ua {
        tls {
                dns cloudflare {env.CF_API_TOKEN}
        }
        reverse_proxy http://192.168.0.50:3000
}

5. Links to relevant resources:

@Bruce5051
Thanks for your help!

Check this one:

Check this one:

You can check with this domain SelfHosted.pp.ua
But yes, your curl results are expected because you’re not in my internal network. You are supposed to see all that if you access it externally. I’m using Cloudflare and I have an internal DNS to change the A records.

Here are the internal results:


curl -Ii http://SelfHosted.pp.ua

HTTP/1.1 308 Permanent Redirect
Connection: close
Location: https://SelfHosted.pp.ua/
Server: Caddy
Date: Sun, 25 May 2025 17:33:58 GMT


curl -Ii http://SelfHosted.pp.ua:443

HTTP/1.0 400 Bad Request


curl -k -Ii https://SelfHosted.pp.ua:443

HTTP/2 302
alt-svc: h3=":443"; ma=2592000
content-type: text/plain; charset=utf-8
date: Sun, 25 May 2025 17:35:14 GMT
location: /status/services
vary: Accept
via: 1.1 Caddy
x-frame-options: SAMEORIGIN
content-length: 37


1 Like

Kindly wait for more knowledgeable Caddy community volunteers to assist.

1 Like