What's Actually Happening

Caddy fails to obtain SSL certificates from Let's Encrypt. HTTPS does not work and site is not accessible securely.

The Error You'll See

```bash $ journalctl -u caddy

error: obtaining certificate: example.com: acme: error: 403 :: unauthorized ```

Why This Happens

  1. 1.DNS not resolving to server
  2. 2.Port 80/443 blocked
  3. 3.Firewall blocking ACME challenge
  4. 4.Rate limit exceeded
  5. 5.Caddyfile misconfiguration

Step 1: Check DNS Resolution

bash
dig example.com +short
nslookup example.com
curl http://example.com

Step 2: Check Ports

bash
nc -zv example.com 80
nc -zv example.com 443
ss -tlnp | grep -E '80|443'

Step 3: Check Firewall

bash
iptables -L -n | grep -E '80|443'
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload

Step 4: Check Caddyfile

bash
caddy validate --config /etc/caddy/Caddyfile
cat /etc/caddy/Caddyfile

Step 5: Check Caddy Logs

bash
journalctl -u caddy -f
cat /var/log/caddy/access.log

Step 6: Verify Caddy Running

bash
systemctl status caddy
systemctl restart caddy

Step 7: Test ACME Challenge

bash
curl http://example.com/.well-known/acme-challenge/test
curl -I http://example.com

Step 8: Check Rate Limits

bash
# Let's Encrypt rate limits
# Check: https://letsencrypt.org/docs/rate-limits/
# Use staging for testing:
# In Caddyfile:
{
  acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

Step 9: Force Certificate Retry

bash
# Clear certificate cache:
rm -rf /var/lib/caddy/.local/share/caddy/certificates/
systemctl restart caddy

Step 10: Use DNS Challenge

```caddyfile { acme_dns cloudflare API_TOKEN }

example.com { respond "Hello" } ```

  • [Fix Nginx Upstream Timed Out](/articles/fix-nginx-upstream-timed-out)
  • [Fix Let's Encrypt Certificate Not Renewing](/articles/fix-letsencrypt-certificate-not-renewing)