1. The problem I’m having:
I have a reverse proxy set up on my domain (elsebody.com), which points to an internal IP address (192.168.8.100) – and it works perfectly.
However, when I try to do the same with a subdomain (o.elsebody.com), the dns challenge fails with a tls.obtain bad request (400).
The API key from Ionos is associated with my customer account, not a specific domain, so should work on subdomains too.
DNS checker shows the A records for both parent and subdomain have propagated, and point to the same IP address.
Any thoughts on how to get reverse proxy working with my subdomain?
2. Error messages and/or full log output:
```
PS D:\Dropbox\JimBin\Caddy> caddy run --watch
2025/08/16 03:58:09.724 ←[34mINFO←[0m maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined
2025/08/16 03:58:09.725 ←[34mINFO←[0m GOMEMLIMIT is updated {"package": "github.com/KimMachineGun/automemlimit/memlimit", "GOMEMLIMIT": 15071322931, "previous": 9223372036854775807}
2025/08/16 03:58:09.725 ←[34mINFO←[0m using adjacent Caddyfile
2025/08/16 03:58:09.726 ←[34mINFO←[0m adapted config to JSON {"adapter": "caddyfile"}
2025/08/16 03:58:09.727 ←[33mWARN←[0m Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies {"adapter": "caddyfile", "file": "Caddyfile", "line": 14}
2025/08/16 03:58:09.736 ←[34mINFO←[0m admin admin endpoint started {"address": "localhost:2019", "enforce_origin": false, "origins": ["//localhost:2019", "//[::1]:2019", "//127.0.0.1:2019"]}
2025/08/16 03:58:09.736 ←[34mINFO←[0m tls.cache.maintenance started background certificate maintenance {"cache": "0xc00051f700"}
2025/08/16 03:58:09.736 ←[34mINFO←[0m http.auto_https 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}
2025/08/16 03:58:09.736 ←[34mINFO←[0m http.auto_https enabling automatic HTTP->HTTPS redirects {"server_name": "srv0"}
2025/08/16 03:58:09.736 ←[35mDEBUG←[0m http.auto_https adjusted config {"tls": {"automation":{"policies":[{"subjects":["o.elsebody.com"]},{}]}}, "http": {"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","transport":{"protocol":"http","tls":{"insecure_skip_verify":true}},"upstreams":[{"dial":"192.168.8.211:443"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
2025/08/16 03:58:09.737 ←[35mDEBUG←[0m http starting server loop {"address": "[::]:443", "tls": true, "http3": false}
2025/08/16 03:58:09.737 ←[34mINFO←[0m http enabling HTTP/3 listener {"addr": ":443"}
2025/08/16 03:58:09.737 ←[34mINFO←[0m http.log server running {"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2025/08/16 03:58:09.737 ←[35mDEBUG←[0m http starting server loop {"address": "[::]:80", "tls": false, "http3": false}
2025/08/16 03:58:09.737 ←[33mWARN←[0m http HTTP/2 skipped because it requires TLS {"network": "tcp", "addr": ":80"}
2025/08/16 03:58:09.737 ←[33mWARN←[0m http HTTP/3 skipped because it requires TLS {"network": "tcp", "addr": ":80"}
2025/08/16 03:58:09.737 ←[34mINFO←[0m http.log server running {"name": "remaining_auto_https_redirects", "protocols": ["h1", "h2", "h3"]}
2025/08/16 03:58:09.738 ←[34mINFO←[0m http enabling automatic TLS certificate management {"domains": ["o.elsebody.com"]}
2025/08/16 03:58:09.738 ←[35mDEBUG←[0m events event {"name": "started", "id": "6d10e7bc-8d2d-465e-bc94-9915703829d6", "origin": "", "data": null}
2025/08/16 03:58:09.739 ←[34mINFO←[0m autosaved config (load with --resume flag) {"file": "C:\\Users\\Jim\\AppData\\Roaming\\Caddy\\autosave.json"}
2025/08/16 03:58:09.739 ←[34mINFO←[0m serving initial configuration
2025/08/16 03:58:09.739 ←[34mINFO←[0m watcher watching config file for changes {"config_file": "Caddyfile"}
2025/08/16 03:58:09.740 ←[34mINFO←[0m tls storage cleaning happened too recently; skipping for now {"storage": "FileStorage:C:\\Users\\Jim\\AppData\\Roaming\\Caddy", "instance": "b84f29cf-3e27-4800-8496-286b891c4f37", "try_again": "2025/08/17 03:58:09.740", "try_again_in": 86400}
2025/08/16 03:58:09.740 ←[34mINFO←[0m tls finished cleaning storage units
2025/08/16 03:58:09.750 ←[34mINFO←[0m tls.obtain acquiring lock {"identifier": "o.elsebody.com"}
2025/08/16 03:58:09.752 ←[34mINFO←[0m tls.obtain lock acquired {"identifier": "o.elsebody.com"}
2025/08/16 03:58:09.752 ←[34mINFO←[0m tls.obtain obtaining certificate {"identifier": "o.elsebody.com"}
2025/08/16 03:58:09.753 ←[35mDEBUG←[0m events event {"name": "cert_obtaining", "id": "0a8cefef-0a00-41cb-b7bf-ffb92de45603", "origin": "tls", "data": {"identifier":"o.elsebody.com"}}
2025/08/16 03:58:09.753 ←[35mDEBUG←[0m tls created CSR {"identifiers": ["o.elsebody.com"], "san_dns_names": ["o.elsebody.com"], "san_emails": [], "common_name": "", "extra_extensions": 0}
2025/08/16 03:58:09.754 ←[35mDEBUG←[0m tls.obtain trying issuer 1/1 {"issuer": "acme-v02.api.letsencrypt.org-directory"}
2025/08/16 03:58:09.754 ←[35mDEBUG←[0m tls.issuance.acme using existing ACME account because key found in storage associated with email {"email": "default", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
2025/08/16 03:58:09.754 ←[35mDEBUG←[0m tls.issuance.acme using existing ACME account because key found in storage associated with email {"email": "", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
2025/08/16 03:58:09.755 ←[34mINFO←[0m tls.issuance.acme waiting on internal rate limiter {"identifiers": ["o.elsebody.com"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": ""}
2025/08/16 03:58:09.755 ←[34mINFO←[0m tls.issuance.acme done waiting on internal rate limiter {"identifiers": ["o.elsebody.com"], "ca": "https://acme-v02.api.letsencrypt.org/directory", "account": ""}
2025/08/16 03:58:09.755 ←[34mINFO←[0m tls.issuance.acme using ACME account {"account_id": "https://acme-v02.api.letsencrypt.org/acme/acct/2594289706", "account_contact": []}
2025/08/16 03:58:10.604 ←[35mDEBUG←[0m http request {"method": "GET", "url": "https://acme-v02.api.letsencrypt.org/directory", "headers": {"User-Agent":["Caddy/2.10.0 CertMagic acmez (windows; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["995"],"Content-Type":["application/json"],"Date":["Sat, 16 Aug 2025 03:58:11 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2025/08/16 03:58:10.605 ←[35mDEBUG←[0m creating order {"account": "https://acme-v02.api.letsencrypt.org/acme/acct/2594289706", "identifiers": ["o.elsebody.com"]}
2025/08/16 03:58:11.106 ←[35mDEBUG←[0m http request {"method": "HEAD", "url": "https://acme-v02.api.letsencrypt.org/acme/new-nonce", "headers": {"User-Agent":["Caddy/2.10.0 CertMagic acmez (windows; amd64)"]}, "response_headers": {"Cache-Control":["public, max-age=0, no-cache"],"Date":["Sat, 16 Aug 2025 03:58:11 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["9_RDYWV0wZ1Mftqg_nsI9O78u5jlIQOQUvXII2xKv3Ttl1k3v0E"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2025/08/16 03:58:11.271 ←[35mDEBUG←[0m http request {"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/new-order", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.10.0 CertMagic acmez (windows; amd64)"]}, "response_headers": {"Boulder-Requester":["2594289706"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["348"],"Content-Type":["application/json"],"Date":["Sat, 16 Aug 2025 03:58:11 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/2594289706/418362240357"],"Replay-Nonce":["trI9TC2kWPGJIXZ37maBLuq3Hf8iOTkzQZVpETmFWJz9aqQMaUc"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 201}
2025/08/16 03:58:11.357 ←[35mDEBUG←[0m http request {"method": "POST", "url": "https://acme-v02.api.letsencrypt.org/acme/authz/2594289706/569588950837", "headers": {"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.10.0 CertMagic acmez (windows; amd64)"]}, "response_headers": {"Boulder-Requester":["2594289706"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["822"],"Content-Type":["application/json"],"Date":["Sat, 16 Aug 2025 03:58:11 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["9_RDYWV0wDmpV5IQ3792xVD6hOMpMz9Nx_2kvI8BZJo7WvZxs0w"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]}, "status_code": 200}
2025/08/16 03:58:11.358 ←[34mINFO←[0m trying to solve challenge {"identifier": "o.elsebody.com", "challenge_type": "dns-01", "ca": "https://acme-v02.api.letsencrypt.org/directory"}
```
3. Caddy version:
PS D:\Dropbox\JimBin\Caddy> caddy version
v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U=
4. How I installed and ran Caddy:
Downloaded Caddy v2.10.0 plus Ionos module v1.2.0 from downloads page
a. System environment:
Windows 11 (no Docker, VM etc.)
b. Command:
```
PS D:\Dropbox\JimBin\Caddy> caddy run --watch
```
c. Service/unit/compose file:
n/a
d. My complete Caddy config:
```
{
# Use Ionos API key for DNS challenges
acme_dns ionos {redacted.redacted}
debug
}
o.elsebody.com {
reverse_proxy 192.168.8.211:443 {
transport http {
tls_insecure_skip_verify
}
}
}
```