Reliable Let's Encrypt renewals on RHEL / Rocky
A certificate can only be renewed in its last 30 days. A cron job that tries once a month can miss that window after a single failure, and the certificate expires.
Use the packaged timer
The EPEL certbot package ships a systemd timer that runs twice a day:
sudo systemctl enable --now certbot-renew.timer
systemctl list-timers certbot-renew.timer
Remove any old monthly certbot cron entries.
Reload the web server after renewal
A renewed certificate isn't used until the web server reloads. Add a deploy hook:
sudo install -m 755 /dev/stdin /etc/letsencrypt/renewal-hooks/deploy/reload-web.sh <<'H'
#!/bin/sh
systemctl reload httpd 2>/dev/null || systemctl reload nginx
H
Or, for the packaged timer, set it in /etc/sysconfig/certbot:
DEPLOY_HOOK="--deploy-hook 'systemctl reload httpd'"
If you must use cron
17 3,15 * * * root /usr/bin/certbot renew -q --deploy-hook "systemctl reload httpd"
Test
sudo certbot renew --dry-run