Caddy with Cloudflare DNS for external domain / subdomain

Hi folks.

First, thanks for the wonderful Caddy server. I have been learning about this and so far so good on regular setup with individual domains.

Currently, I have been trying to host third party subdomain on my caddy server. For e.g.,
abc.userdomain.com will point to abc.myowndomain.com. This will generate automatic HTTPS. In this, I have been stuck with the following problems. My apologies - I had to replace the actual domains with dummy ones. Hope this is ok.

myowndomain.com is owned by me.
userdomain.com is owned by user, not me.

Appreciate your help and time. Hope, you would be able to point me to the right direction.

1. The problem I’m having:

I have been trying to enable automatic HTTPS for abc.userdomain.com that points to abc.myowndomain.com. I was able to enable HTTPS for abc.myowndomain.com. However, after mapping via CNAME in DNS, from abc.myowndomain.com to abc.userdomain.com, HTTPS is not working. Browsing it on a web browser, it returns ERR_TIMEOUT.

2. Error messages and/or full log output:

Apr 21 08:10:46 page caddy[1800243]: {"level":"error","ts":1745219446.2702575,"msg":"cleaning up solver","identifier":"abc.userdomain.com","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.abc.userdomain.com\" (usually OK if presenting also failed)","stacktrace":"github.com/mholt/acmez/v3.(*Client).solveChallenges.func1\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:318\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:363\ngithub.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).obtainOnDemandCertificate\n\tgithub.com/caddyserver/certmagic@v0.21.6/handshake.go:538\ngithub.com/caddyserver/certmagic.(*Config).getCertDuringHandshake\n\tgithub.com/caddyserver/certmagic@v0.21.6/handshake.go:376\ngithub.com/caddyserver/certmagic.(*Config).GetCertificateWithContext\n\tgithub.com/caddyserver/certmagic@v0.21.6/handshake.go:92\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ConnectionPolicy).buildStandardTLSConfig.func1\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/connpolicy.go:276\ncrypto/tls.(*Config).getCertificate\n\tcrypto/tls/common.go:1196\ncrypto/tls.(*serverHandshakeStateTLS13).pickCertificate\n\tcrypto/tls/handshake_server_tls13.go:475\ncrypto/tls.(*serverHandshakeStateTLS13).handshake\n\tcrypto/tls/handshake_server_tls13.go:61\ncrypto/tls.(*Conn).serverHandshake\n\tcrypto/tls/handshake_server.go:54\ncrypto/tls.(*Conn).handshakeContext\n\tcrypto/tls/conn.go:1568\ncrypto/tls.(*Conn).HandshakeContext\n\tcrypto/tls/conn.go:1508\nnet/http.(*conn).serve\n\tnet/http/server.go:1971"}
Apr 21 08:10:46 page caddy[1800243]: {"level":"debug","ts":1745219446.6358094,"msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/pTn5hGBGSxoPQjxiVjmX5w","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.9.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["134"],"Content-Type":["application/json"],"Date":["Mon, 21 Apr 2025 07:10:46 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["9ZOzcn5jhXs6mCuUilE2q0GkrisoyvjxEHJyYPSWT-s"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
Apr 21 08:10:46 page caddy[1800243]: {"level":"error","ts":1745219446.6376493,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"abc.userdomain.com","issuer":"acme.zerossl.com-v2-DV90","error":"[abc.userdomain.com] solving challenges: presenting for challenge: adding temporary record for zone \"userdomain.com.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme.zerossl.com/v2/DV90/order/h7gWs_w0zxzFp7owRAqmuQ) (ca=https://acme.zerossl.com/v2/DV90)"}
Apr 21 08:10:46 page caddy[1800243]: {"level":"debug","ts":1745219446.6385844,"logger":"events","msg":"event","name":"cert_failed","id":"46afee1b-771f-40f9-b351-e789943caddd","origin":"tls","data":{"error":{},"identifier":"abc.userdomain.com","issuers":["acme-v02.api.letsencrypt.org-directory","acme.zerossl.com-v2-DV90"],"renewal":false}}
Apr 21 08:10:46 page caddy[1800243]: {"level":"error","ts":1745219446.6405444,"logger":"tls.obtain","msg":"will retry","error":"[abc.userdomain.com] Obtain: [abc.userdomain.com] solving challenges: presenting for challenge: adding temporary record for zone \"userdomain.com.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme.zerossl.com/v2/DV90/order/h7gWs_w0zxzFp7owRAqmuQ) (ca=https://acme.zerossl.com/v2/DV90)","attempt":2,"retrying_in":120,"elapsed":64.537514089,"max_duration":2592000}
Apr 21 08:12:42 page caddy[1800243]: {"level":"info","ts":1745219562.0930731,"logger":"tls.obtain","msg":"releasing lock","identifier":"abc.userdomain.com"}
Apr 21 08:12:42 page caddy[1800243]: {"level":"debug","ts":1745219562.0999882,"logger":"http.stdlib","msg":"http: TLS handshake error from 116.86.23.114:59686: context canceled"} 
Apr 21 08:10:46 page caddy[1800243]: {"level":"error","ts":1745219446.2702575,"msg":"cleaning up solver","identifier":"abc.userdomain.com","challenge_type":"dns-01","error":"no memory of presenting a DNS record for \"_acme-challenge.abc.userdomain.com\" (usually OK if presenting also failed)","stacktrace":"github.com/mholt/acmez/v3.(*Client).solveChallenges.func1\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:318\ngithub.com/mholt/acmez/v3.(*Client).solveChallenges\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:363\ngithub.com/mholt/acmez/v3.(*Client).ObtainCertificate\n\tgithub.com/mholt/acmez/v3@v3.0.0/client.go:136\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).doIssue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:477\ngithub.com/caddyserver/certmagic.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/certmagic@v0.21.6/acmeissuer.go:371\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ACMEIssuer).Issue\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/acmeissuer.go:249\ngithub.com/caddyserver/certmagic.(*Config).obtainCert.func2\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:626\ngithub.com/caddyserver/certmagic.doWithRetry\n\tgithub.com/caddyserver/certmagic@v0.21.6/async.go:104\ngithub.com/caddyserver/certmagic.(*Config).obtainCert\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:700\ngithub.com/caddyserver/certmagic.(*Config).ObtainCertAsync\n\tgithub.com/caddyserver/certmagic@v0.21.6/config.go:505\ngithub.com/caddyserver/certmagic.(*Config).obtainOnDemandCertificate\n\tgithub.com/caddyserver/certmagic@v0.21.6/handshake.go:538\ngithub.com/caddyserver/certmagic.(*Config).getCertDuringHandshake\n\tgithub.com/caddyserver/certmagic@v0.21.6/handshake.go:376\ngithub.com/caddyserver/certmagic.(*Config).GetCertificateWithContext\n\tgithub.com/caddyserver/certmagic@v0.21.6/handshake.go:92\ngithub.com/caddyserver/caddy/v2/modules/caddytls.(*ConnectionPolicy).buildStandardTLSConfig.func1\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/caddytls/connpolicy.go:276\ncrypto/tls.(*Config).getCertificate\n\tcrypto/tls/common.go:1196\ncrypto/tls.(*serverHandshakeStateTLS13).pickCertificate\n\tcrypto/tls/handshake_server_tls13.go:475\ncrypto/tls.(*serverHandshakeStateTLS13).handshake\n\tcrypto/tls/handshake_server_tls13.go:61\ncrypto/tls.(*Conn).serverHandshake\n\tcrypto/tls/handshake_server.go:54\ncrypto/tls.(*Conn).handshakeContext\n\tcrypto/tls/conn.go:1568\ncrypto/tls.(*Conn).HandshakeContext\n\tcrypto/tls/conn.go:1508\nnet/http.(*conn).serve\n\tnet/http/server.go:1971"}

Apr 21 08:10:46 page caddy[1800243]: {"level":"debug","ts":1745219446.6358094,"msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/pTn5hGBGSxoPQjxiVjmX5w","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.9.1 CertMagic acmez (linux; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["134"],"Content-Type":["application/json"],"Date":["Mon, 21 Apr 2025 07:10:46 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["9ZOzcn5jhXs6mCuUilE2q0GkrisoyvjxEHJyYPSWT-s"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}

Apr 21 08:10:46 page caddy[1800243]: {"level":"error","ts":1745219446.6376493,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"abc.userdomain.com","issuer":"acme.zerossl.com-v2-DV90","error":"[abc.userdomain.com] solving challenges: presenting for challenge: adding temporary record for zone \"userdomain.com.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme.zerossl.com/v2/DV90/order/h7gWs_w0zxzFp7owRAqmuQ) (ca=https://acme.zerossl.com/v2/DV90)"}

Apr 21 08:10:46 page caddy[1800243]: {"level":"debug","ts":1745219446.6385844,"logger":"events","msg":"event","name":"cert_failed","id":"46afee1b-771f-40f9-b351-e789943caddd","origin":"tls","data":{"error":{},"identifier":"abc.userdomain.com","issuers":["acme-v02.api.letsencrypt.org-directory","acme.zerossl.com-v2-DV90"],"renewal":false}}

Apr 21 08:10:46 page caddy[1800243]: {"level":"error","ts":1745219446.6405444,"logger":"tls.obtain","msg":"will retry","error":"[abc.userdomain.com] Obtain: [abc.userdomain.com] solving challenges: presenting for challenge: adding temporary record for zone \"userdomain.com.\": got error status: HTTP 400: [{Code:6003 Message:Invalid request headers ErrorChain:[{Code:6111 Message:Invalid format for Authorization header}]}] (order=https://acme.zerossl.com/v2/DV90/order/h7gWs_w0zxzFp7owRAqmuQ) (ca=https://acme.zerossl.com/v2/DV90)","attempt":2,"retrying_in":120,"elapsed":64.537514089,"max_duration":2592000}

Apr 21 08:12:42 page caddy[1800243]: {"level":"info","ts":1745219562.0930731,"logger":"tls.obtain","msg":"releasing lock","identifier":"abc.userdomain.com"}

Apr 21 08:12:42 page caddy[1800243]: {"level":"debug","ts":1745219562.0999882,"logger":"http.stdlib","msg":"http: TLS handshake error from 116.86.23.114:59686: context canceled"}

3. Caddy version:

v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=

4. How I installed and ran Caddy:

Install Caddy and xCaddy for Cloudflare DNS

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

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 update

sudo apt install caddy

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list

sudo apt update

sudo apt install xcaddy

a. System environment:

Ubuntu 20.04.6 LTS, x86-64
Systemd:
systemd 245 (245.4-4ubuntu3.24)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid

b. Command:

sudo systemctl status caddy
sudo systemctl restart caddy

d. My complete Caddy config:

{
   on_demand_tls {
        ask http://localhost:5555/
    }

    debug
    email me@myowndomain.com
    acme_dns cloudflare {env.CLOUDFLARE_API_KEY}
}

(app) {
    log {
        output stdout
    }

    # Resolve the root directory for the app
    root * /home/ubuntu/apps/myowndomain.com/public

    # Provide Zstd and Gzip compression
    encode zstd gzip

    # Allow caddy to serve static files
    file_server {
		index index.html
	}

    # Enable PHP-FPM
    php_fastcgi unix//run/php/php8.4-fpm.sock

    header -Server
}

http://, https:// {

    tls {
        on_demand
    }

    import app
}

http://localhost:5555 {
	respond 200
}

5. Links to relevant resources: