2026-03-30 · SSLLet's EncryptUbuntusystemd

certbot.timer on Ubuntu 22.04: How to Check, Fix, and Verify Auto-Renewal

The certbot.timer is active. The service shows enabled. Your certificate expired anyway. Here is how to verify the full renewal pipeline is actually working — not just that the timer exists.

On Ubuntu 22.04, certbot uses a systemd timer instead of a cron job for automatic certificate renewal. This is the right way to do it — systemd timers are more reliable than cron for this use case. But if you're used to seeing a cron entry for certbot and it's not there, you might wonder whether renewal is actually working.

Here's how to verify it, fix it if it's broken, and understand what's happening.

Check if the certbot timer is active

sudo systemctl status certbot.timer

You want to see Active: active (waiting). If you see inactive (dead) or failed — your certificates are not auto-renewing.

The full output should look something like this:

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Mon 2026-03-23 09:00:00 UTC; 6 days ago
    Trigger: Thu 2026-03-30 09:52:00 UTC; 3h 41min left
   Triggers: ● certbot.service

The Trigger: line shows when it will next run. If this is missing or shows a date in the past — the timer has stopped.

Check when certbot last ran

sudo systemctl status certbot.service

This shows the last execution of the renewal service itself. Look for ExecStart timestamp and whether it exited successfully.

# Also check the certbot log directly:
sudo journalctl -u certbot.service --since "30 days ago" | tail -30

You want to see renewal attempts and either no renewal was necessary (cert not expiring soon) or Congratulations, all renewals succeeded.

Fix: timer exists but is not enabled

sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
sudo systemctl status certbot.timer

Fix: timer is missing entirely

If systemctl status certbot.timer returns Unit certbot.timer could not be found — certbot was installed without the systemd timer, or it was installed via pip instead of apt.

# Check how certbot is installed:
which certbot
certbot --version

# If installed via snap (recommended on Ubuntu 22.04):
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# The snap version includes the timer automatically:
sudo systemctl status snap.certbot.renew.timer

Ubuntu 22.04 note: The recommended certbot installation method is via snap, not apt. The snap version uses snap.certbot.renew.timer instead of certbot.timer. Check both if you are unsure which you have installed.

Test renewal without actually renewing

sudo certbot renew --dry-run

This simulates the renewal process without touching your certificates. It will catch the most common failure modes — port 80 blocked, DNS not pointing to the server, nginx ACME challenge misconfiguration. Run this monthly as a sanity check.

If dry-run fails: your certificates are not auto-renewing even if the timer shows as active. Fix the underlying issue before your next expiry date.

Common failure: port 80 blocked

Let's Encrypt HTTP-01 challenges require port 80 to be accessible. If your Nginx config redirects all port 80 traffic to HTTPS before the ACME challenge location, renewal fails silently.

# Your Nginx port 80 block must have this BEFORE the redirect:
server {
    listen 80;
    server_name yourdomain.com;

    # ACME challenge — must come before the HTTPS redirect
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

Common failure: certbot timer active but cert still expires

The timer runs twice daily but only renews certificates within 30 days of expiry. If you want to confirm the full renewal pipeline works, force a renewal:

# Force renewal regardless of expiry date:
sudo certbot renew --force-renewal

# Or renew a specific domain:
sudo certbot renew --cert-name yourdomain.com --force-renewal

Use this only to test. Forcing renewal unnecessarily counts against Let's Encrypt rate limits (5 renewals per domain per week).

Set up a monitoring check

The timer being active does not mean renewal will succeed. Add a weekly dry-run to cron as a belt-and-suspenders check:

# Add to crontab (crontab -e):
0 9 * * 1 certbot renew --dry-run 2>&1 | grep -E "error|failed|FAILED" | mail -s "Certbot dry-run check" you@yourdomain.com

This emails you only if the dry-run finds errors — silent on success.

Check SSL certificate expiry across all your domains at once — 200-day warnings, CDN detection, and chain validation.

Open SSL Checker →

Quick reference

# Check timer status:
sudo systemctl status certbot.timer
sudo systemctl status snap.certbot.renew.timer  # if using snap

# Check last renewal:
sudo systemctl status certbot.service
sudo journalctl -u certbot.service --since "7 days ago"

# Test without renewing:
sudo certbot renew --dry-run

# Enable if disabled:
sudo systemctl enable --now certbot.timer

# List all certificates and expiry:
sudo certbot certificates

Related guides