Crontab Certificate Renewal is missed

Hello Everyone,
I’d like to discuss my problem with you and I have been facing this on multiple servers.

Certificate Renewal is being missed and all the configurations are correct, and when I run the dry run test, it runs successfully, however when I trace the let’s encrypt log I get no renewal, and the certificate is due to renewal as it’s 30 days before expiration date.

My Environment:

  • OS: CentOS 7
  • WebServer: nginx

This is how I obtained the certificate:

certbot certonly --webroot -w /var/www/html -d -d

I do the certificate renewal through crontab

0 4 * * 0 /bin/certbot renew --post-hook “nginx -s reload” >> /var/log/letsencrypt-renew.log

and Here’s the certificate renewal history of the certificate:

The second renewal done successfully which is, while the third renewal was not attempted, so I had to renew the certificate myself manually after the expiration of the certificate.

Here’s my configurations

version = 0.8.1
cert = /etc/letsencrypt/live/
privkey = /etc/letsencrypt/live/
chain = /etc/letsencrypt/live/
fullchain = /etc/letsencrypt/live/
authenticator = webroot
installer = None

and this is the output of the --dry-run test:

Processing /etc/letsencrypt/renewal/
** DRY RUN: simulating ‘certbot renew’ close to cert expiry
** (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/ (success)
** DRY RUN: simulating ‘certbot renew’ close to cert expiry
** (The test certificates above have not been saved.)

Could you post the logs where it’s failing?

No Failures happened, and this is the when list the files the /var/log/letsencrypt directory

There’s no log file created within jun 16 and 2 august, which means that the cronjob did not run within this period

The Jun 16 log file is an attempt that was not due to renewal
The Aug 2 log file is my manual attempt to renew the certificate

drwx------. 2 root root 4.0K Aug 9 17:35 .
drwxr-xr-x. 11 root root 4.0K Aug 6 03:39 …
-rw-r–r--. 1 root root 4.7K Aug 9 17:36 letsencrypt.log
-rw-r–r--. 1 root root 70K Aug 9 17:08 letsencrypt.log.1
-rw-r–r--. 1 root root 4.6K May 14 04:00 letsencrypt.log.10
-rw-r–r--. 1 root root 64K Aug 2 15:27 letsencrypt.log.2
-rw-r–r--. 1 root root 64K Aug 2 15:21 letsencrypt.log.3
-rw-r–r--. 1 root root 4.6K Jun 16 03:20 letsencrypt.log.4
-rw-r–r--. 1 root root 64K Jun 16 03:20 letsencrypt.log.5
-rw-r–r--. 1 root root 4.6K Jun 11 04:00 letsencrypt.log.6
-rw-r–r--. 1 root root 4.6K Jun 4 04:00 letsencrypt.log.7
-rw-r–r--. 1 root root 4.6K May 28 04:00 letsencrypt.log.8
-rw-r–r--. 1 root root 4.6K May 21 04:00 letsencrypt.log.9

First note is that it’s recommended to run renewal twice daily, no weekly. Second, if it’s not actually running, you should probably try and figure out why your cron isn’t executing commands as expected. What’s the August 9th logs? Are those also only manual renewals? You should see log entries from certbot every time it runs, indicating that a renewal was or was not attempted and the outcome if it was attempted.

I would try adding webroot to the renewal process:
/bin/certbot renew --webroot -w /var/www/html --post-hook “nginx -s reload” >> /var/log/letsencrypt-renew.log

Also, webroot uses http and, unless you are bypassing the acme-challenges, one of the sites is re-re-re-directing the http (to https then http then https):
–2017-08-09 12:14:47--
Resolving (…
Connecting to (||:80… connected.
HTTP request sent, awaiting response… 301 Moved Permanently
Location: [following]
–2017-08-09 12:14:48--
Connecting to (||:443… connected.
HTTP request sent, awaiting response… 302 Moved Temporarily
Location: [following]
–2017-08-09 12:14:48--
Resolving (…
Connecting to (||:80… connected.
HTTP request sent, awaiting response… 302 Moved Temporarily
Location: [following]
–2017-08-09 12:14:48--
Connecting to (||:443… connected.
HTTP request sent, awaiting response… 200 OK

Adding --webroot is unnecessary and not best practice in general. Renewal uses the same authorization method in use for issuance - this would be webroot in this case.

Webroot can follow https redirects - that’s not an issue.

But the redirect leads to a completely different domain (and IP).
Could be problematic if not considered in the design.

Good point - noticed the domains, but the IP may be problematic.

Something has changed since the last working renewal.
Maybe the redirections.
Maybe the webroot folder was moved.
Maybe the acme-challenge alias was changed.

I want to point out by way of agreement with this concern that certbot renew is designed to work in environments where you have perhaps dozens of different certificates which are obtained by all different authentication methods. In that case, specifying authentication information related to just one of the certificates would be a recipe for disaster (failed renewals) because it would be used for various certificates that it didn’t actually apply to.

The intended design is indeed to specify the authentication parameters with certonly or run, and then have Certbot remember them for the future and supply them automatically with renew. If you need to change them, the recommended way is via a single (potentially --force-renewal) renewal with certonly and appropriate parameters, which should be saved.

Here’s my nginx configuration:

server {
listen 80 default_server;
return 301 https://$host$request_uri;
server {
listen 443 default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;

    location =/{
    rewrite (.*) redirect;

    location ~ /.well-known {
            root /var/www/html;
            allow all;


according to these configuration, we want to redirect the root location to go to, but when it requires .well-known locations, it servers over https.

The webroot location wasn’t changed, and the as you can see the configurations are correct.

so This mean that It’s better to use certbot renew with out --webroot, did I get this right ?

Yes do those a --dry-run test by me, just to make sure the configuration was right, and when I traced the log /var/log/letsencrypt/letsencrypt.log, the renewal dry-run was successful.

I’ll try to update my cronjob with this, but the execution of the renewal cron during the 30 days before expiration wasn’t unreasonable, that’s why I’m trying to debug the environment, and I can see all the configurations are right till now.

try placing a test file at:
and see if it is accessible via the Internet

Maybe also /var/www/html/.well-known/acme-challenge/test.txt for greater realism.

Doesn't that essentially remove the "/.well-known" portion form the URL?

We’ve definitely had people have trouble with that issue before. It might be more correct with root /var/www/html/.well-known in this case.

When /.well-known is requested by the acme challenge, it’s created, and I can access secret.txt, so I think the root is fine

I have another question, If the post-hook did not successfully run, will the certificate be issued ?
as I got this in the log file

Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/ (success)
Unable to find post-hook command nginx in the PATH.
(PATH is /usr/bin:/bin)

Yes, the cert was issued (renewed) and can be found at

The post-hook simply restarts nginx to ensure the latest cert is in use.

I see that you have managed to get and use the latest cert:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.