What Caddy automates
When a public domain appears in a valid Caddy configuration, Caddy normally activates automatic HTTPS: it obtains a trusted certificate, renews it before expiration and redirects HTTP to HTTPS. This is automation, not magic. The domain must resolve to the server, the relevant challenge traffic must reach Caddy, the service must be running and the certificate authority must be able to validate control.
Caddy's automatic HTTPS documentation lists the usual public-domain requirements: correct A or AAAA records, external access to ports 80 and 443, the domain present in the configuration, and a persistent writable data directory. Keep /var/lib/caddy across upgrades; certificate state should not disappear with each deployment.
Step 1: verify DNS
Run these from your own computer, not only from the server. Replace the domain.
dig +short A example.com
dig +short AAAA example.com
dig +short A www.example.com
The A result must be the server's public IPv4. If an AAAA result exists, test that exact IPv6 route. Remove the AAAA record if the server is not intentionally serving IPv6. Also inspect dig CAA example.com if you created CAA records; an overly restrictive policy can prevent the selected certificate authority from issuing.
Step 2: verify the network path
Check both the cloud firewall or security group and UFW. From the server, confirm which process listens on the ports.
sudo ufw status verbose
sudo ss -ltnp | grep -E ':(80|443)\b'
systemctl status caddy --no-pager
Caddy should own or receive traffic for ports 80 and 443. If Nginx, Apache or a stale process owns a port, decide which web server should be active instead of repeatedly restarting both. From another network, curl -I http://example.com should reach the server; a timeout usually points to routing or firewall before it points to certificate syntax.
Step 3: validate configuration and read the first error
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
journalctl -u caddy --since '15 minutes ago' --no-pager
Look for the first certificate or listener error, not only the final retry message. DNS errors, connection timeouts, refused connections and rate limits have different fixes. Correct the cause and reload once; rapid random edits can make the log harder to understand.
Step 4: inspect the public response
curl -4 -I https://example.com
curl -I https://www.example.com
openssl s_client -connect example.com:443 -servername example.com </dev/null
The certificate name must include the host being tested, dates must be current, and the redirect should lead to the chosen canonical name. A browser warning on one device may be a stale local cache, but verify with curl and a second network before assuming that.
Common failure patterns
What I learned
I used to call every browser warning a certificate problem. In reality, most of my failures happened one layer earlier: stale DNS, an accidental AAAA record or a closed cloud firewall. Now I test in the same order every time—name, route, listener, configuration, certificate—and stop at the first broken layer.
Finish line
HTTP should redirect to HTTPS, the canonical host should return 200, both IPv4 and any published IPv6 route should work, and Caddy logs should contain no repeating issuance error. Continue with monitoring, backup and recovery before calling the site finished.