How to renew certificates generated from a csr


I’ve generated the certificate for my domain and it works. I’m using HPKP, so I generated it using a csr. I use lighttpd on my server, so I’ve used certbot’s standalone mode for authentication. The command I ran was

service lighttpd stop;./certbot-auto certonly --non-interactive --standalone --csr=/certs/;service lighttpd start

I got three files from that: 0000_cert.pem 0000_chain.pem and 0001_chain.pem in the working directory.

When I try to dry-run the renewal, I’m told “no renewals were attempted”

./certbot-auto renew --dry-run --non-interactive --standalone --pre-hook="service lighttpd stop" --post-hook="service lighttpd start"

I’ve looked through the docs and I can’t see the solution. How do I renew?


Could it be the “–dry-run” the cause ? Also in the past, the certificate were not renewed if too eager.


Isn’t the point of --dry-run to simulate the renewal, even if too early? It’s basically for testing the setup without waiting to be eligible for renewal, right?


The renew subcommand does not work with certificates you acquired using --csr. The way to renew these certificates is to essentially repeat the command you used to obtain it in the first place. Adding --keep might be useful if you plan to automate this in a daily cronjob, though I have not investigated if this works for the --csr use-case.

You might also need --force-renewal if you want to test this and the client refuses to get the certificate because the current certificate is still fairly new.


Wouldn’t that burn out my 5 certificates per week rate limit if I did it daily? Seems more than a little silly to get a new certificate every day. I could run it weekly, but that seems like a bit of risk.

Looking at the docs for --keep, I don’t understand what that is supposed to do. Does it cause certbot not to request the new certificate until it needs renewal?


Yep, that’s the idea. It should do what the renew subcommand does, that is, renew the certificate 30 days prior to its expiration date. The reason why it’s recommended to run it daily (or even twice a day) is to avoid issues when there’s downtime - this gives you 30 attempts to contact the CA server, one of those better work.

Caveat: I have not used --keep in combination with --csr before, so you’d have to test this behaviour or hope for the best.


I don’t think --keep has done anything at all with --csr. I still get new cert files.


I see - in that case, I guess with --csr you’re responsible for ensuring you only invoke the client when it’s time to actually renew, and possibly parse the list of files to find the most recently issued certificate. I can’t really think of a simpler solution for this use-case (at least with certbot; an alternative client might be a better fit here).


Unless I’m wrong about what --keep is actually doing, it seems I’ll need to come up with something creative.


To confirm, if you used --csr, certificates are not registered under /etc/letsencrypt at all and Certbot doesn’t know about them after they’re issued, so renew will never renew them.

A comment in certbot/ says

This works differently in the CSR case (for now) because we don’t
have the privkey, and therefore can’t construct the files for a lineage.
So we just save the cert & chain to disk :confused:

I think we’ve failed to document that in our regular documentation anywhere.


Thanks for the confirmation. Do you have any best practices for automatically renewing in this case? Scripting is no problem for me, but I’m new to LE and still trying to fill in the blanks.


I’ve filed an issue requesting to mention this in our documentation.


@thommcgrath, do you need to use a CSR? If you have the private key available on the same machine, you could just give a list of domains with -d, which is the preferred method with Certbot and will allow automated renewal. The CSR approach is kind of a backwards-compatibility feature for people who find it important to use a CSR for some reason. The biggest benefit is not having to have the private key available on the machine, but of course if the machine is your TLS server, you’ll need to have it in order to provide the service.

If you do want to continue using a CSR, you can get the expiry time of a certificate by running something like

openssl x509 -in cert.pem -enddate -noout

You’d see output like

notAfter=Apr 4 23:50:38 2025 GMT

You can get this as a Unix time with

date -d "$(openssl x509 -in cert.pem -enddate -noout | cut -d= -f2)" +%s

and get the current Unix time with date +%s, and you could then subtract them and see if the result is smaller than a specified number of seconds in order to decide to renew.


I should probably say “if you’re willing to have the private key available on the same machine”, because the default behavior (currently somewhat inconvenient to change) with -d instead of --csr is to generate a new private key for each certificate, including for each renewal.


At the moment at least, I must use a CSR. If I had started this months ago, it’d be a different story. I have HPKP enabled on my site so I need to use my existing key or one of the backups for now. I have a 3 month validity period, but my commercial certificate expires on the 8th of November. So as I said, for now, I need to use a CSR to retain use of my private key.

In the future, maybe I’ll pin to a LE intermediate or remove the pinning entirely. But for now, I have to do it this way.

Thanks for the tip about pulling the expiration from the certificate. That’ll help a lot. I think I’m going to write a script to watch the expiration and use acme-tiny to request a new certificate as necessary.


We should be able to modify Certbot to allow using an existing key instead of regenerating it. There is existing code to do this; it just requires adding a way to invoke it. But that wouldn’t directly solve your problem because there is no code yet to generate a renewable certificate lineage from a CSR and private key, or to use an existing private key with a fresh certificate request.

I can create an issue to propose these further features, but they probably won’t land in Certbot before November 8.


The CSR approach is useful for people who employ proper separation of privileges. The LE client only needs access to the private key because it’s convenient, not because it’s needed or actually reasonable.

If you look at the LE client objectively, it’s a massive piece of code that modifies your server config, self-updates from the Internet and runs as root. I get that it’s convenient, but from a sensible admin’s perspective, it’s pure madness.


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