Certbot says "No renewals were attempted"

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is: paleozoic.cloud

I ran this command:
sudo docker compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot -d paleozoic.cloud

Note that I had previously run the python-certbot-nginx script by mistake. I hadn't realized it was not appropriate for a docker setup. I'm guessing that gave me a certificate and now letsencrypt believes I have a valid certificate and won't issue a new one? I deleted the python-certbot installation.

It produced this output:
Saving debug log to /var/log/letsencrypt/letsencrypt.log


No renewals were attempted.


My web server is (include version): nginx/1.31.8

The operating system my web server runs on is (include version): ubuntu 26.04

My hosting provider, if applicable, is: na

I can login to a root shell on my machine (yes or no, or I don't know): Yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): No

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): 5.8.0

It looks to me like you were never issued a certificate for that domain. At least not in the last 180 days. Is the question about pay.paleozoic.cloud ? Because a cert for that name was issued by GoDaddy today.

Let's Encrypt will issue up to 5 identical certs in a week before you get rate limited. That would be poor practice to request so many I am stating this to counter your "guess" that LE is not issuing another one.

Certbot requests certs from Let's Encrypt. These are two distinct pieces (an ACME Client and LE as the ACME Server).

The message from Certbot says you don't have any previously issued certs in its configuration so there is nothing for Certbot to do. When Certbot gets a cert it makes a renewal config file for that. A common mistake in containers is not having the Certbot data in persistent storage. You should refer to: Get Certbot — Certbot 5.9.0.dev0 documentation

If you have problems getting (your first) cert let us know what happens so we can help further.

that message comes from certbot itself, not the server. it found an existing certificate for that name in /etc/letsencrypt that isn't due for renewal, so it skipped issuing. add --force-renewal to your certonly command if you need a fresh one now.

Thanks Rachel. I'll try that. I had the domain on an AWS server that I shut down a month or so ago. I've restarted on a new server yesterday.

Still no luck. Here's the command I tried:

sudo docker compose run --rm certbot certonly --webroot -w /var/www/certbot -d paleozoic.cloud -d ://paleozoic.cloud --force-renewal
Container driftless-certbot-run-330e803ea1ff Creating 
Container driftless-certbot-run-330e803ea1ff Created 
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

There are public logs for every issued cert (called CT Logs). I don't see any history of a cert for this domain paleozoic.cloud in the past year by any issuer. I saw the one for your pay subdomain but that's it.

That's an invalid format for that second -d command (://paleozoic.cloud). Was that just a copy/paste problem? What were you trying to do with a second -d?

The no renewals attempted error is from a Certbot renew command request. For some reason your container is trying a renew instead of or in addition to the command you sent.

Since Certbot has no config for a past cert there is nothing for it to do.

Have you reviewed the Certbot docker link I provided previously? Because it looks to me like that isn't setup right.

@rachelwilson A --force-renewal has no meaning on a certonly request. It only applies to renew and should be avoided except in rare cases. This is not one of those.

I'm using docker compose and have a line in there as an entrypoint to do a certbot renewal. Maybe it is just executing that entrypoint rather than my cert request.

certbot:
    image: certbot/certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

It was suggested to me to run the renew every 12h. Is that a bit excessive? once a week or month should be sufficient no? I'll try to chase down why it is executing the entrypoint rather than a cert request.

what shows?:
sudo docker compose run --rm certbot certificates

Yes, every 12H is the current recommendation. Once a week or month is not sufficient. The CA (Let's Encrypt) may have to revoke certs. You need to check for renew often so your cert is renewed in that case. This is rare but can happen. Once a month is definitely poor. A single problem like with comms or CA issue can prevent a renew. That means you wouldn't even try for another month by which time you cert may be expired. Follow the recommendation.

You are running nginx on Ubuntu. Why not just use the snap install for Certbot and use the --nginx plugin for that? The snap install sets up a systemd timer for renewal. Much easier than sorting out your container I'd think

Certbot snap install:

In retrospect, you are right, i think. However, I started with this complex docker compose setup with nginx and my backend -- so i figure i'll see how many grey hairs i can develop.
I commented out the entrypoint line in the docker compose yaml. Looks like it made a certificate. I'll see if it is in the right place etc. and let you know. Much appreciate the help.

I'm running that in the shell command line after the nginx, certbot and backend docker services are up and running.

show us the output of that [request for list of certificates]

Requesting a certificate for paleozoic.cloud and www.paleozoic.cloud

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/paleozoic.cloud/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/paleozoic.cloud/privkey.pem
This certificate expires on 2027-01-27.
These files will be updated when the certificate renews.

NEXT STEPS:
- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See https://certbot.org/renewal-setup for instructions.

Looks like I got a certificate. Unfortunately, looks like it is not one to be trusted.

1#1: cannot load certificate "/etc/letsencrypt/live/paleozoic.cloud": PEM_read_bio_X509_AUX() failed (SSL: error:0480006C:PEM routines::no start line:Expecting: TRUSTED CERTIFICATE)

If all you're looking for is a certificate to use with nginx, you may want to just use nginx's built-in module for requesting certificates and forget certbot entirely.

My first attempt was with that. It didn't play well with the docker setup. Not quite sure why I'm doing this with docker other that I can debug my backend in a docker container on my laptop and then just send it to the public facing server.

You did. Likely nginx can't read it from where you stored it. Those should be in common, persistent storage.

There's no reason you can't use snap for the Cert and continue your backend in a container.

@petercooperjr I agree the nginx acme-module is nice but I am pretty sure (but not 100%) that Ubuntu version does not include it in the standard apt nginx package. If that's the case it takes more admin skills to setup nginx with that module. That's really been the biggest hurdle given it's fairly new.

Also, that isn't the name of a cert file. There should be a fullchain.pem in the directory

Yes, file is there:

ls /etc/letsencrypt/live/paleozoic.cloud
README         cert.pem       chain.pem      fullchain.pem  privkey.pem

It's the name of the folder [where the certs are]