How to monitor Caddy

Monitor Caddy by checking every site over HTTPS with certificate expiry alerts, because Caddy renews certificates on its own and you only notice failed renewals when they expire. Inside, watch the service, reverse_proxy errors in the journal or JSON access log, and validate configs before reloading. Vigil covers both with an uptime monitor and its agent.

Updated · by PuzariCloud · commands checked against current releases

What can go wrong with Caddy

  • Renewal fails silently. Caddy renews about a third of a certificate's life before expiry (around 30 days for 90-day certificates). If port 80 or 443 is blocked, DNS moved, or a CA rate limit is hit, it retries quietly in the log for weeks until the certificate expires.
  • Upstream down. reverse_proxy returns 502 when no upstream answers. Without active health checks Caddy keeps sending traffic to a dead backend.
  • Config reload rejected. caddy reload with an invalid Caddyfile is refused and the old config keeps running, so a change you think is live is not.
  • Storage not writable. Certificates and ACME accounts live in the data directory (/var/lib/caddy/.local/share/caddy for the packaged service). If it is not writable, issuance fails on every restart.
  • On-demand TLS abuse. With on_demand_tls and no ask endpoint, anyone pointing a domain at you can make Caddy request certificates until you hit rate limits.

The signals that matter, with alert thresholds

SignalAlert whenWhy it matters
HTTPS status and latency per sitenon-2xx/3xx, or p95 > 1 sWhat users see.
Certificate days left≤ 14 (Caddy should have renewed at ~30)Renewal has been failing for two weeks.
5xx share of requests> 5% over at least 20 requestsUpstream trouble.
Errors mentioning obtain/renew in the journalany, repeatedACME failures before they expire anything.
caddy servicenot activeDown on this host.

Thresholds are starting points. Tune them after a week of data: an alert nobody acts on should be raised or removed.

How to check Caddy by hand

Validate before reloading
caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Recent certificate errors
journalctl -u caddy --since '24 hours ago' | grep -iE 'obtain|renew|acme' | grep -i error
What config is actually loaded (admin API)
curl -s localhost:2019/config/ | head -c 600
Expiry of the certificate being served
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate

How to watch Caddy with Vigil

  1. In New monitor create an Uptime monitor per site. Leave the SSL alert at 14 days: Caddy should have renewed long before, so an alert means renewal is broken, with two weeks left to fix it.
  2. Add the host under Servers and run the one-line installer it shows (curl -fsSL https://puzaricloud.in/install-server-agent.sh | sh -s -- --token <token>). The agent is one Python file with no dependencies; CPU, memory, disk, inode and load rules start working with the first report. The agent picks up Caddy access logs in /var/log/caddy/*.log (enable log in the site block), which feed the per-endpoint 5xx and p95 rules.
  3. Add caddy to the systemd services to watch and caddy to the journal units to ship. Then add a log alert rule for error lines containing obtain so renewal trouble pages you on the first failures.
  4. If you serve customer domains with on-demand TLS, add a Domain & DNS monitor on your own apex so a DNS change that breaks validation is caught too.

Every alert goes to the channels you pick: email, Slack, Telegram, Discord, Microsoft Teams, Pushover, webhooks or on-call paging. Failures are confirmed by a second check before anyone is woken up.

Caddy monitoring FAQ

Caddy handles HTTPS automatically. Why monitor certificates at all?

Automatic issuance depends on DNS, open ports and the CA. When any of these breaks, Caddy logs the error and retries; nothing tells you until the certificate expires. The expiry alert is the safety net for the automation.

Does Caddy expose metrics?

Yes, in Prometheus format on the admin endpoint (localhost:2019/metrics); per-request HTTP metrics have to be switched on in the global options on recent releases. You can scrape them with the agent's Prometheus exporters setting.

Is this how Vigil itself runs?

Yes. Vigil's own sites and customers' status-page domains sit behind Caddy with on-demand TLS, watched by uptime monitors with SSL expiry alerts.

Vigil by PuzariCloud

Watch Caddy without stitching five tools together

Uptime and API checks, heartbeats, server and database metrics, traces, errors and logs in one place, with one incident and one alert when something breaks. Every feature is on every plan, including Free.