How to get a free Let's Encrypt certificate for nginx or Apache on your own server, check renewal, add a domain, issue a wildcard certificate and fix common errors.
Contents
Let's Encrypt issues certificates for free, and certbot obtains them and renews them for you. This article covers a cloud server. On cPanel hosting, certificates are issued without any action from you: SSL certificates in cPanel.
Before you start
- The domain points to your server: the A record is the server’s IP address. If the domain also has an AAAA record, it must point to this server too — otherwise the check goes over IPv6 to a different address and fails.
- The site opens over
http://, and port 80 is open in the firewall — How to open a port.
To check the records: dig +short example.co.uk A and dig +short example.co.uk AAAA.
Installation
sudo apt install certbot python3-certbot-nginx # Ubuntu, Debian
sudo dnf install epel-release # AlmaLinux
sudo dnf install certbot python3-certbot-nginxFor Apache, install python3-certbot-apache instead of python3-certbot-nginx.
Getting a certificate
sudo certbot --nginx -d example.co.uk -d www.example.co.ukcertbot asks for your email address and your agreement to the terms, checks the domain, obtains the certificate and adds the HTTPS settings to nginx for you. For Apache, use --apache. List every name that should open over HTTPS with -d: www is a separate name.
If you manage the web server settings yourself and certbot should not touch them, get the certificate only:
sudo certbot certonly --webroot -w /var/www/example.co.uk -d example.co.uk -d www.example.co.ukThe files appear in /etc/letsencrypt/live/example.co.uk/: fullchain.pem is the certificate with its chain, and privkey.pem is the key. In nginx:
ssl_certificate /etc/letsencrypt/live/example.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.co.uk/privkey.pem;Renewal
A certificate is valid for 90 days, and certbot renews it automatically about a month before it expires. Let’s Encrypt is gradually shortening the lifetime: from 10 February 2027 it will be 64 days, and from 16 February 2028 it will be 45. If renewal works, you don’t need to do anything.
On Ubuntu and Debian, renewal is enabled straight away. On AlmaLinux, enable it yourself:
sudo systemctl enable --now certbot-renew.timerCheck that renewal will work — this command changes nothing:
sudo certbot renew --dry-runIf you used certonly, add a reload after renewal so that the web server picks up the new certificate:
printf '#!/bin/sh\nsystemctl reload nginx\n' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginxsudo certbot certificates — it shows the expiry date.Adding or removing a domain
sudo certbot certificates # which certificates exist
sudo certbot --nginx --cert-name example.co.uk -d example.co.uk -d www.example.co.uk -d shop.example.co.uk
sudo certbot delete --cert-name old.example.co.uk # delete a certificateWith --cert-name, certbot replaces the list of names in the existing certificate with the names given in -d — so list all the names you need, not just the new one.
Wildcard: *.example.co.uk
Let’s Encrypt issues a certificate for all subdomains at once only with DNS validation: you need to add a TXT record _acme-challenge to the domain’s zone.
sudo certbot certonly --manual --preferred-challenges dns -d 'example.co.uk' -d '*.example.co.uk'certbot shows you the value of the record and waits until you have added it. A certificate obtained this way will not renew itself — you will have to repeat the process by hand. For automatic renewal you need a certbot plugin for your DNS provider that works through its API. If you don’t need a wildcard, it is simpler to list the subdomains with -d.
Common errors
Timeout during connect— Let’s Encrypt could not reach the server on port 80: either the firewall blocks it or the domain points elsewhere.unauthorizedorInvalid responsewith a 404 code — the check arrived, but not at this site: another server is answering on the AAAA record, there is a differentserver_namein nginx, or a redirect sends the validation URL elsewhere.too many certificates already issued— you have hit the limit: you can get a certificate for the same set of names no more than 5 times a week. Wait, and don’t issue a new certificate on every attempt — use the--dry-runoption for experiments.CAA record— the domain has a CAA record that does not allow Let’s Encrypt. Addletsencrypt.orgto it, or delete the record.
If the site opens over HTTPS but the browser complains about mixed content, see Mixed content on HTTPS. For redirecting from http to https, see Redirecting to HTTPS.
Didn’t find the answer? Ask our support team — we’ll help.