Guide
Certbot systemd timer not running
certbot.timer disabled or missing—enable systemd renewal units so certificates renew before notAfter.
Updated Apr 2, 2026 815 words
Without certbot.timer or equivalent cron, certificates age until external monitors scream—enable and verify scheduling first.
When this happens
Last letsencrypt.log entry is months old while notAfter approaches. Immutable infrastructure replaces VMs weekly but golden images never baked in systemctl enable certbot.timer. Autoscaling groups rebuilt from stale AMIs silently drop timer enablement even when application deploy pipelines remain healthy.
Golden AMI hardening disabled systemd timers assuming Kubernetes handles TLS. Ephemeral CI runners should never hold production lineages without external orchestration. Developers running manual certonly on laptops occasionally disable timers thinking human process replaces automation.
First response
certbot.timer disabled or missing—enable systemd renewal units so certificates renew before notAfter.
Searches for certbot timer not running usually mean automated renewal failed, succeeded locally but never reached the TLS listener, or hit Let's Encrypt rate limits. The fix is almost always permissions, challenge reachability, or a missing reload—not buying a longer-lived commercial cert as the first move.
For Certbot systemd timer not running, read the ACME or panel error verbatim, run a dry-run renewal if your stack supports it, then confirm what certificate strangers receive on port 443 after you deploy. Certificate files on disk lie; only live handshakes matter for users.
Systems without a firing certbot.timer discover expiry only from external monitors. Debian and RHEL ship systemd units, but cloud images often omit enablement after golden-image bake. Verify systemctl list-timers before blaming Let's Encrypt. Triage should capture timestamps, account URLs, and the last Boulder error type before infrastructure changes widen blast radius. Pause destructive retries until you can cite the last Boulder error type and the challenge mechanism in use; random package reinstalls rarely fix presentation gaps.
See also ACME DNS-01 challenge propagation delays and ACME HTTP-01 challenge failed 403.
Why renewal failed
Debian and Fedora ship certbot.timer triggering renew twice daily. Fleet managers should export timer elapse metrics per autoscaling group; one bad AMI strandings hundreds of identical hosts at the same notAfter. Scheduling is part of TLS architecture, not an optional convenience.
Snap and certbot packages use different unit names—mixing them duplicates or disables automation. If you delegate TLS to Kubernetes, turn off host-level timers deliberately—but document that choice so platform migrations do not leave double abandonment. Golden images should fail build if renewal automation is disabled.
Containers without systemd need explicit cron sidecars. Infrastructure compliance scans should assert timer enabled like they assert sshd configuration. Escalate with timestamps, hostnames, and serial comparisons attached so the next engineer does not repeat already-failed renew attempts.
The timer triggers certbot renew twice daily with jitter. If masked or disabled, certificates age silently unless another cron exists. Snap certbot uses different unit names than apt packages—mixing install methods duplicates or deletes timers. Clarify in tickets whether failure is validation, issuance, deploy, or listener presentment—teams too often mix these phases when reading logs. Scheduling gaps are preventable compliance findings; auditors increasingly ask how you know automation ran between manual issuances.
Timer missing is not the same as renew failure—no attempts occur. Manual certbot works while automation never scheduled. Host inventory without timer verification is a compliance gap; Terraform should assert enabled timers when VMs own TLS, not only when apps run inside Kubernetes.
Common causes
These patterns drive most certbot timer not running tickets. They explain why automation logs look green while browsers or APIs still break.
Ansible image disabled timers assuming external vault handled TLS. Chef or Ansible bootstrap flags that disable unused services sometimes blanket-disable certbot.timer along with guest agents.
systemd-notify failures after snapd upgrade left timer inactive.
Clock in UTC container without systemd at all. Containers bind-mount host /etc/letsencrypt without timer sidecar—host timer renews certs containers never reload. Immutable laptops and ephemeral dev machines should not hold production lineage paths without an external renew orchestrator.
Diagnose
List timers and confirm certbot service last run. Prove negative scheduling failure with timer metadata before debugging ACME; absent timers masquerade as mysterious CA outages near day thirty.
systemctl list-timers 'certbot*'
systemctl status certbot.timer
journalctl -u certbot.service -n 30
Check for duplicate cron and timer both fighting. Inspect /var/log/syslog for certbot unit start entries. Compare /var/lib/letsencrypt mtimes with timer calendar; large gaps prove scheduling gap not CA issue. Attach hardware inventory ID with timer status so bare-metal gaps do not hide behind virtual machine reporting alone.
Fix step-by-step
Follow this sequence for certbot systemd timer not running. Capture command output after each step so the next responder can pick up without rerunning destructive changes.
- Identify certbot install method (apt, snap, pip).
- Enable correct timer unit for that method.
- Confirm randomized delay and next elapse time.
- Run certbot service once manually and check exit code.
- Ensure renew configs exist for all production lineages.
- Set calendar reminders until automation proven.
- Add monitoring on timer last trigger.
- Document ownership of TLS automation on each host class.
- Archive redacted ACME logs and openssl transcripts in the ticket before closing.
- Schedule a follow-up dry-run before the next natural renewal window.
- Export timer status into your compliance evidence pack for the quarter.
Verify the live certificate
OpenSSL
echo | openssl s_client -connect HOST:443 -servername HOST 2>/dev/null | openssl x509 -noout -dates -subject -issuer
Replace HOST with the public hostname on the certificate. Run the same command after any reload or deploy change; acceptance means notAfter moved forward and serial changed versus the incident-opening capture.
How to read the output
Timer issues show up as unchanged notAfter approaching; openssl confirms urgency. External notAfter trending toward thirty days with silent letsencrypt.log proves scheduling failure earlier than package errors surface in ad hoc manual renew tests.
curl
curl -vI --connect-timeout 10 https://HOST/ 2>&1 | grep -Ei 'expire|SSL certificate|subject:|issuer:'
Replace HOST with the public hostname users request.
Roll out and verify
Run systemctl enable --now certbot.timer for the package you installed.
Confirm next trigger time with systemctl status certbot.timer. Add infrastructure tests in Packer builds asserting timer enabled state before AMI publish.
Alert if timer not fired in 48 hours via systemd exporter. Fleet reporting that lists hosts missing enabled certbot timers should block production promotion in release gates. Publish a short post-incident note listing which hop served stale TLS and which command proved the fix so the next renewal inherits a checklist.
What to automate
Export systemd timer last run metrics; alert if older than forty-eight hours. Export certbot timer last trigger as a metric on every VM role that owns TLS.
ssldays backs timer monitoring with objective handshake expiry on public names. ssldays backs timer hygiene with external handshake monitoring. ssldays closes the observability gap when systemd timers exist but never fire on rebuilt hosts.
Frequently asked questions
Cron vs timer?
Pick one; duplicate schedules race hooks and confuse logs. Paste systemctl list-timers snippet showing certbot entry.
Silent renew failures?
Timer may run but renew fails—monitor exit codes, not only timer fire. Paste systemctl list-timers snippet showing certbot entry.
VMs without systemd?
Use /etc/cron.d/certbot and log aggregation on cron mail. Paste systemctl list-timers snippet showing certbot entry.
Can Kubernetes replace host timers?
If TLS terminates only in the cluster, yes—use cert-manager. Hybrid setups with TLS on VMs still need host timers or centralized orchestration pushing PEMs. Document single ownership to avoid both layers assuming the other renews.
Monitor this hostname on a schedule
Live certificate checks and renewal reminders — not guesswork from PEM files.