How to Automate SSL Certificate Renewal

By VigilDog Team · August 22, 2026 · 6 min read

Almost every expired-certificate outage happens on a server someone thought was already automated. The renewal ran, or was supposed to, but the new certificate never actually reached the service that serves traffic. To automate SSL certificate renewal properly you need three things working together: automatic issuance, automatic reload, and independent monitoring that tells you when the chain quietly failed.

Why manual renewal always eventually fails

Certificates from public CAs are short-lived by design — Let's Encrypt issues 90-day certs, and the industry is moving shorter, not longer. A 90-day cadence is too frequent to track by hand and too infrequent to remember. The calendar reminder gets snoozed, the person who owned it leaves, or the renewal happens but nobody reloads the web server.

The fix is to remove humans from the renewal path entirely and use the ACME protocol, which automates the proof-of-control and issuance steps. Once issuance is automatic, the only remaining risk is the delivery of the new cert into your running service — which is exactly where most "but it was automated" outages come from.

Root CAin the trust storeIntermediatemust be installedYour certificateleaf, for your domain
The TLS certificate chain of trust

The baseline: certbot and ACME

On most Linux servers, certbot is the standard ACME client. A single renewal command checks every certificate it manages and only reorders the ones within 30 days of expiry, so it's safe to run often:

Run `certbot renew --quiet` twice a day. Modern certbot installs a systemd timer (`certbot.timer`) or cron entry that does exactly this out of the box — verify it exists rather than assuming. Before trusting it, prove the whole flow with `certbot renew --dry-run`, which exercises issuance against the staging environment without touching your real certificates or rate limits.

  • Cron equivalent: `0 0,12 * * * certbot renew --quiet`
  • Check the timer: `systemctl list-timers certbot.timer`
  • Test the full path safely: `certbot renew --dry-run`

The step everyone forgets: the deploy hook

A renewed certificate on disk does nothing until the service loads it. Nginx, Apache, HAProxy, and most others read the cert at startup and hold it in memory — so a fresh cert sitting in `/etc/letsencrypt/live` while the old one is still being served is the classic silent failure.

Attach a deploy hook so the reload happens only when a certificate actually renews: `certbot renew --quiet --deploy-hook "systemctl reload nginx"`. The `--deploy-hook` runs solely after a successful renewal, which avoids reloading your server twice a day for nothing. For anything terminating TLS outside the web server — a load balancer, a mail server, a container — the hook is where you push the new cert to that system.

Wildcards and split setups: DNS-01

The default HTTP-01 challenge proves control by serving a file over port 80, which is fine for a single host. Wildcard certificates (`*.example.com`) can't use it — they require the DNS-01 challenge, which proves control by writing a TXT record to your zone.

Automate DNS-01 with a provider plugin so the client creates and removes that TXT record itself, for example `certbot certonly --dns-cloudflare --dns-cloudflare-credentials /root/.secrets/cf.ini -d '*.example.com' -d example.com`. The lightweight `acme.sh` client is a popular alternative with built-in DNS API support for dozens of providers. Either way, once DNS-01 is scripted, wildcard renewal is as hands-off as any other.

Automation still needs a backstop

Here's the uncomfortable truth: automation fails silently. A rotated API token breaks the DNS challenge, a hook throws an error nobody reads, a CAA record change blocks your CA, or one host in a fleet was never enrolled. The renewal script exits non-zero into a log file no human opens, and everything looks fine until the cert expires on a Saturday.

That's why the last layer is external monitoring that checks the certificate the way a browser sees it — from outside your server, watching the actual expiry date and chain. Confirm a live cert any time with our free SSL checker, and if a renewal has already lapsed, what to do when a certificate expires walks through recovery. Continuous SSL monitoring is the piece that turns "we automated it" into "we'd know within minutes if it broke."

Free download

Domain & SSL monitoring checklist

The silent failures that take a site down — an expired certificate, a lapsed domain, an incomplete chain — are

Get the checklist

Frequently asked

How often should I run certbot renew?
Twice a day is the recommended cadence. The command only renews certificates within 30 days of expiry, so frequent runs are safe and give it multiple chances to recover from a transient failure before the deadline.
My certificate renewed but the site still shows the old one — why?
The service is still serving the cert it loaded at startup. You need a deploy hook (for example, reloading nginx) so the running service picks up the newly renewed certificate.
If renewal is automated, do I still need SSL monitoring?
Yes. Automation fails silently — broken hooks, expired API tokens, or an un-enrolled host. External monitoring catches the lapse before your visitors do.

Automate renewal, then verify it held

VigilDog watches your certificates from the outside and alerts you well before expiry — the backstop that catches the silent renewal failures automation can't see.

Free for your first domain · No card