Report this

What is the reason for this report?

How to Issue Let's Encrypt Wildcard Certificates with Certbot

Updated on June 3, 2026
How to Issue Let's Encrypt Wildcard Certificates with Certbot

Introduction

Issuing a wildcard certificate for names like *.example.com with Certbot and Let’s Encrypt always uses the ACME DNS-01 challenge (the DNS challenge), not HTTP-01. You prove control of the domain by publishing TXT records under _acme-challenge, not by placing HTTP files on a single host. Wildcard issuance first landed with Let’s Encrypt ACMEv2 in March 2018, and that requirement has not changed since then.

In this tutorial you will:

  1. Confirm wildcard DNS resolves the way you expect.
  2. Install Certbot plus the DNS plugin that matches your provider, or run a manual DNS challenge when you have no API access.
  3. Store API credentials safely when you automate DNS.
  4. Issue certbot certonly with the right flags (including combinations that cover the apex and wildcard together, multiple apex domains in one certificate, and multi-level subdomain trees), verify PEM files, and plan unattended certbot renew with deploy hooks that reload your web server automatically.
  5. Configure NGINX or Apache to serve TLS traffic using the issued certificate files.

The steps apply to common Linux distributions. Exact package names differ, so you should keep your vendor documentation open while you work.

Key takeaways:

  • A single certificate for *.example.com covers one label under the apex, for example api.example.com. The same certificate does not cover example.com itself unless you add a second name, and does not cover dev.api.example.com.
  • Wildcard issuance always uses DNS validation. The HTTP-01 challenge remains valid for specific hostnames, yet the CA still requires DNS proof for wildcard issuance.
  • Automated renewal for wildcard certificates depends on a DNS plugin or another unattended DNS update path. A fully manual TXT workflow still works for issuance, yet you must repeat TXT edits for every renewal unless you automate DNS.
  • Production environments should automate renewal using systemd timers or cron jobs because Let’s Encrypt certificates expire every 90 days.
  • Staging requests help you debug DNS or rate limit issues without consuming production quota. Add --staging while you test, then remove the flag for trusted certificates.

Why wildcard certificates require DNS-01

HTTP-01 proves control of one hostname at a time by serving a token from that host. A wildcard pattern matches many future hostnames, including names that do not point at your server yet, so a file-based check would not prove control of the full zone. DNS-01 instead asks you to place _acme-challenge TXT records at the same DNS authority that answers for every name under the zone, which aligns with wildcard semantics.

Manual DNS validation compared to a Certbot DNS plugin

Topic Manual --manual DNS DNS plugin (DigitalOcean example)
API token Not required Needs DNS write scope
Best fit Rare or air-gapped use Production renewals
Renewal Manual TXT unless you script DNS certbot renew updates TXT
Interaction Pauses for TXT entry Runs unattended

Prerequisites

You should already have:

If you run Nginx or Apache without wildcard automation yet, bookmark How To Secure Nginx with Let’s Encrypt on Ubuntu and How To Secure Apache with Let’s Encrypt on Ubuntu.

Step 1: Setting up wildcard DNS

Point *.example.com to the server or load balancer that should handle HTTPS traffic. A typical record looks like this:

*.example.com.   3600  IN  A  203.0.113.1

The * label matches a single leftmost name. *.example.com answers for app.example.com but not for example.com or dev.app.example.com.

If you are setting up this record for the first time, consider temporarily lowering the TTL (shown as 3600 seconds above) to a smaller value such as 300 before you make changes. A lower TTL means DNS resolvers discard cached answers sooner, so any corrections propagate faster. Once the record is stable and Let’s Encrypt has validated successfully, you can raise the TTL back to a higher value to reduce query load on your nameservers.

Note: See DigitalOcean DNS record management documentation.

Check propagation with dig or host:

  1. dig +short A app.example.com
  1. host app.example.com

Expect an A or CNAME answer before you continue.

Step 2: Installing the correct Certbot DNS plugin

Certbot supports three installation paths for DNS validation: fully manual mode (no API required), a package-manager-installed plugin, and a snap-installed plugin. Choose the option that matches how Certbot was installed on your system and whether you have API access to your DNS provider.

Option A: Manual DNS validation

Use manual mode when you lack API access or you only need a one-time certificate:

  1. sudo certbot certonly --manual --preferred-challenges dns \
  2. -d '*.example.com' -d 'example.com'

Certbot prints the TXT values. You add them at your DNS host, wait for propagation, then continue in the terminal. This prompt repeats on every renewal, so certbot renew running in a cron job or systemd timer will time out without a human present. See Step 7 for options.

Option B: Automated DNS validation via package manager

Install the provider plugin from your distribution. DigitalOcean’s package is named python3-certbot-dns-digitalocean:

  1. sudo apt install python3-certbot-dns-digitalocean

On Fedora or RHEL 8+ use dnf:

  1. sudo dnf install python3-certbot-dns-digitalocean

List plugins to confirm registration:

  1. certbot plugins

You should see dns-digitalocean alongside standalone and webroot.

Option C: Automated DNS validation via snap

On Ubuntu 22.04 and later, Certbot is distributed as a snap, and the package-manager version of the plugin may not be available or may lag behind. Install the Certbot snap first if you have not already done so:

  1. sudo snap install --classic certbot

Tell snapd that Certbot is permitted to use plugins that run with elevated privileges:

  1. sudo snap set certbot trust-plugin-with-root=ok

Install the DigitalOcean DNS plugin snap:

  1. sudo snap install certbot-dns-digitalocean

Connect the plugin to Certbot:

  1. sudo snap connect certbot:plugin certbot-dns-digitalocean

Confirm the plugin is visible:

  1. certbot plugins

dns-digitalocean should appear in the output. You are now ready to proceed with credential setup in Step 3.

For a focused walkthrough of DNS validation on Ubuntu 20.04, read our Ubuntu 20.04 DNS validation guide.

Step 3: Configuring the Certbot plugin

Create a credentials file only you can read. A recommended path for production systems is /etc/letsencrypt/certbot-creds.ini, which keeps credentials alongside other Certbot state. Alternatively, you can place the file in your home directory:

  1. sudo nano /etc/letsencrypt/certbot-creds.ini

DigitalOcean expects a single key:

/etc/letsencrypt/certbot-creds.ini
dns_digitalocean_token = paste_your_write_scoped_token_here

Create a DigitalOcean API token with DNS write (not full account) scope under API -> Tokens. Limiting the token to DNS write prevents broader access if exposed. After saving, restrict the credentials file so only root can read it:

  1. sudo chmod 600 /etc/letsencrypt/certbot-creds.ini

Restrict the file permissions to avoid Certbot security warnings.

Step 4: Retrieving the certificate

Use certbot certonly for all wildcard issuance. The --nginx and --apache installer modes do not handle wildcard virtual hosts, so certonly is the only supported path. The subsections below walk through plugin-based issuance, staging rehearsals, the expected output files, and how to combine multiple apex domains and multi-level subdomains in a single certificate command.

Automated example with the DigitalOcean plugin

Request both the apex and wildcard in one command when you serve traffic on both:

  1. sudo certbot certonly \
  2. --dns-digitalocean \
  3. --dns-digitalocean-credentials /etc/letsencrypt/certbot-creds.ini \
  4. --dns-digitalocean-propagation-seconds 60 \
  5. -d 'example.com' \
  6. -d '*.example.com'

The --dns-digitalocean-propagation-seconds flag sets how long Certbot waits for DNS changes to take effect after creating the _acme-challenge TXT record. The default is 10 seconds, but propagation can take 30 to 60 seconds or longer on DigitalOcean. Setting this flag to 60 is usually safer; use 120 or higher if verification fails. This flag exists for other DNS plugins as well, though the name and recommended value may differ by provider.

--nginx and --apache installers do not configure wildcard virtual hosts for you, so certonly remains the supported path for wildcard issuance.

Staging rehearsal

Add --staging while you test DNS or hook scripts. Staging certificates are not trusted by browsers, yet they avoid production rate limits. Switch to production (remove --staging) only when the dry run succeeds end to end.

Expected output

On success, Certbot writes PEM files under /etc/letsencrypt/live/example.com/, where the directory name matches the first -d value you passed:

  • fullchain.pem
  • privkey.pem
  • chain.pem
  • cert.pem

Multi-domain and multi-level wildcard coverage

A single certbot certonly command can include multiple Subject Alternative Names (SANs) using separate -d flags. For current SAN limits, consult Let’s Encrypt’s official rate limits. A few patterns that come up often:

  • Apex plus wildcard. This is the most common setup and is already shown in the automated example above. Without the apex name, example.com is not covered by the wildcard alone: *.example.com matches api.example.com but not the bare apex.

  • Multiple apex domains in one certificate. If you manage more than one domain, combining them into a single certificate reduces the number of renewal jobs you need to track:

    1. sudo certbot certonly \
    2. --dns-digitalocean \
    3. --dns-digitalocean-credentials /etc/letsencrypt/certbot-creds.ini \
    4. --dns-digitalocean-propagation-seconds 60 \
    5. -d 'example.com' -d '*.example.com' \
    6. -d 'example.net' -d '*.example.net'

    Because each domain has its own wildcard TXT record to validate, Certbot makes separate API calls to DigitalOcean DNS for each. Both records must propagate before Let’s Encrypt proceeds.

  • Multi-level subdomains. The ACME specification (RFC 8555) limits wildcard issuance to a single label, so *.example.com does not match v2.api.example.com. Issue a separate wildcard for that subdomain tree:

    1. sudo certbot certonly \
    2. --dns-digitalocean \
    3. --dns-digitalocean-credentials /etc/letsencrypt/certbot-creds.ini \
    4. --dns-digitalocean-propagation-seconds 60 \
    5. -d 'api.example.com' \
    6. -d '*.api.example.com'

    That certificate covers api.example.com and one-label subdomains under it (v1.api.example.com, v2.api.example.com), but not example.com or *.example.com.

Step 5: Verifying the certificate

You can inspect issued certificates with openssl, as described in OpenSSL Essentials. Inspect the SAN list to confirm the certificate covers the names you requested:

  1. sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem \
  2. -noout -text | grep -A1 "Subject Alternative Name"

You should see DNS:*.example.com plus any extra -d names you requested. A certificate issued with -d 'example.com' -d '*.example.com' will show both entries.

Also check the validity window to confirm expiry is roughly 90 days out from today:

  1. sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem \
  2. -noout -dates

The output shows notBefore and notAfter timestamps. If notAfter is under 30 days, you might be seeing an old certificate instead of the new one.

Here is a summary of the four PEM files under /etc/letsencrypt/live/example.com/ (see also SSL Verification for how certificate chains are validated):

File Contents Usage
fullchain.pem End-entity certificate plus intermediate CA certificate The file your web server should present to clients
privkey.pem Private key Needed for server’s private credentials
cert.pem End-entity certificate only (no intermediate chain) Useful for inspection, not for ssl_certificate in prod
chain.pem Intermediate CA certificate only Intermediate CA certificate chain used in some TLS configurations.

Step 6: Pointing Nginx or Apache at the PEM files

certbot certonly writes the certificate but does not touch your web server configuration. You need to add the certificate paths and TLS settings to your server blocks manually.

Nginx

The following is a working Nginx server block for a wildcard certificate. The server_name directive uses the wildcard pattern and the apex name so Nginx matches both:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com *.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Paste TLS settings from https://ssl-config.mozilla.org (Nginx, Intermediate)
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 1d;

    # Your application directives go here
    root /var/www/html;
    index index.html;
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com *.example.com;
    return 301 https://$host$request_uri;
}

For the TLS protocol and cipher settings, use the Mozilla SSL Configuration Generator (select Nginx and the Intermediate profile). The generator produces up-to-date ssl_protocols and ssl_ciphers directives matched to your Nginx and OpenSSL versions, which is more reliable than embedding a static cipher string that can become outdated as recommendations evolve.

The ssl_session_cache shared:SSL:10m directive shares a 10 MB TLS session cache (about 40,000 sessions) among all Nginx workers, enabling faster resumed handshakes. ssl_session_timeout 1d sets cached session validity to 1 day.

Note: fullchain.pem includes both the end-entity certificate and the intermediate CA certificate. Always point ssl_certificate at fullchain.pem, not cert.pem, or clients using older trust stores may reject the chain.

Test and reload after edits:

  1. sudo nginx -t && sudo systemctl reload nginx

Apache

The equivalent Apache VirtualHost block. The ServerAlias line with the wildcard pattern is what extends coverage beyond the bare apex name:

<VirtualHost *:443>
    ServerName      example.com
    ServerAlias     *.example.com

    SSLEngine               on
    SSLCertificateFile      /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile   /etc/letsencrypt/live/example.com/privkey.pem

    # Paste TLS settings from https://ssl-config.mozilla.org (Apache, Intermediate)

    DocumentRoot /var/www/html
</VirtualHost>

# Redirect HTTP to HTTPS
<VirtualHost *:80>
    ServerName  example.com
    ServerAlias *.example.com
    RewriteEngine On
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

Use the Mozilla SSL Configuration Generator (select Apache and the Intermediate profile) to get current SSLProtocol and SSLCipherSuite directives matched to your Apache and OpenSSL versions, then paste them in place of the comment above.

The SSLCertificateFile directive points at fullchain.pem, which includes both the end-entity certificate and the intermediate CA certificate. This is the correct approach for Apache 2.4.8 and later; the older SSLCertificateChainFile directive, which was used to supply intermediate certificates separately, was made obsolete in Apache 2.4.8 when SSLCertificateFile was extended to accept the full certificate chain. If you are running Apache 2.4.8 or later, use only SSLCertificateFile with fullchain.pem and remove any existing SSLCertificateChainFile line.

The rewrite-based HTTP redirect requires mod_rewrite. Enable it if it is not already active:

  1. sudo a2enmod rewrite ssl headers

Test and reload:

  1. sudo apachectl configtest && sudo systemctl reload apache2

Commands differ slightly on RHEL (httpd service name).

Step 7: Automating wildcard certificate renewal

This step explains how to set up fully automated certificate renewal with no manual steps. You will learn to avoid manual mode, confirm the DNS plugin is used, check renewal scheduling, and set up a reload hook for your web server.

Why manual-mode certificates do not renew automatically

When you issue a certificate with --manual, Certbot records that choice in /etc/letsencrypt/renewal/example.com.conf:

[renewalparams]
authenticator = manual

Every renewal attempt pauses for a manual TXT record update. In a cron job or systemd timer, that pause means the attempt times out and fails.

When you issue with --dns-digitalocean instead, the renewal config reads:

[renewalparams]
authenticator = dns-digitalocean
dns_digitalocean_credentials = /etc/letsencrypt/certbot-creds.ini

With those values in place, certbot renew completes the DNS-01 challenge without any human input.

Verifying the renewal configuration

Inspect the renewal file to confirm the authenticator is set to your DNS plugin before you rely on unattended renewal:

  1. sudo cat /etc/letsencrypt/renewal/example.com.conf

You should see authenticator = dns-digitalocean under [renewalparams]. If the file still shows authenticator = manual from an earlier issuance, reissue the certificate using the plugin path as shown in Step 4 and Certbot will overwrite the config.

Confirming the systemd timer

On Ubuntu and Debian, Certbot installs a systemd timer that runs the renewal check twice a day (the unit name depends on how you installed Certbot):

systemctl status certbot.timer snap.certbot.renew.timer

systemctl status certbot.timer


If the timer is not present (for example on a system installed with `pip` rather than `apt` or `snap`), add a cron entry that achieves the same:

```bash
0 */12 * * * root certbot renew --quiet

Place that line in /etc/cron.d/certbot; if you instead add it via sudo crontab -e, omit the root field (the username column is only used in /etc/cron.d/* files).

Place that line in /etc/cron.d/certbot or add it with crontab -e under the root user.

Testing renewal logic

Always do a dry run before relying on automatic renewal:

  1. sudo certbot renew --dry-run

A dry run simulates the full ACME exchange, including the DNS-01 challenge, against Let’s Encrypt’s staging environment (not the production CA). If the dry run fails, fix the issue (most often a credentials path mismatch or an API token with insufficient scope) before the real certificate approaches its expiry.

A dry run simulates the full ACME exchange, including the DNS-01 challenge, without writing new files or contacting the production CA. If the dry run fails, fix the issue (most often a credentials path mismatch or an API token with insufficient scope) before the real certificate approaches its expiry.

Reloading services after each successful renewal

Certbot can invoke an arbitrary command immediately after a successful renewal. There are two ways to wire this up.

At issuance time, pass --deploy-hook to certbot certonly:

  1. sudo certbot certonly \
  2. --dns-digitalocean \
  3. --dns-digitalocean-credentials /etc/letsencrypt/certbot-creds.ini \
  4. --dns-digitalocean-propagation-seconds 60 \
  5. -d 'example.com' -d '*.example.com' \
  6. --deploy-hook "systemctl reload nginx"

Certbot saves the hook command into /etc/letsencrypt/renewal/example.com.conf, so it runs automatically on every subsequent renewal. You do not need to pass the flag again.

For existing certificates, drop an executable script into the deploy hooks directory. Certbot scans this directory after every successful renewal run:

  1. sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/sh
systemctl reload nginx

Make the script executable:

  1. sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

Scripts placed here apply to all certificates managed by Certbot on that machine, which is convenient when multiple certificates share the same web server. If you need a hook that applies to only one certificate, use the --deploy-hook approach at issuance time instead.

Deploy hooks run only when a certificate is actually renewed, not when the renewal check finds that the certificate is still valid. Certbot periodically checks whether certificates are close to expiry and renews them automatically when needed. Deploy hooks run only after a successful renewal, making them the appropriate mechanism for reloading services like Nginx or Apache.

Pre- and post-hooks run before and after every renewal attempt, regardless of whether a certificate changed. Use them if you need to stop a web server for standalone challenges that require port 80. For DNS plugins, pre- and post-hooks are usually unnecessary and just add log noise. For typical reloads after renewal, use deploy hooks.

Troubleshooting

TXT record is not propagating

Diagnosis:
Check if the _acme-challenge.example.com TXT record is visible on authoritative nameservers:

  1. dig TXT _acme-challenge.example.com +short

If the expected value does not appear, the DNS record has not propagated.

Resolution:

  • Wait until DNS lookups consistently return the expected TXT record.
  • If using certbot-dns-digitalocean and verification often fails, increase propagation wait time: --dns-digitalocean-propagation-seconds 120.

Certificate does not cover intended hostname

Diagnosis:
If your certificate does not cover example.com but does cover subdomains like api.example.com, you likely requested only a wildcard.

Resolution:
Add both coverage flags when issuing:

  • -d example.com -d '*.example.com'

Wildcards (*.example.com) never include the apex domain.

Sub-subdomains not matching

Diagnosis:
If v2.api.example.com is not covered by your *.example.com certificate, it’s because wildcards only match a single level.

Resolution:
To cover second-level subdomains, request an additional wildcard:

  • -d 'api.example.com' -d '*.api.example.com'

Plugin authentication failures

Diagnosis:
Renewal attempts fail with “auth” plugin errors or DNS API failures.

Resolution:

  • Rotate the API token.
  • Ensure token has DNS write permissions.
  • Check that the credentials file on disk matches the path in your Certbot renewal config (/etc/letsencrypt/renewal/*.conf).

Rate limit errors from Let’s Encrypt

Diagnosis:
“Too many certificates” or other rate limit messages.

Resolution:

  • Temporarily use the staging server with --staging to test and debug until resolved.
  • After fixing the root cause, try again without --staging.

Renewal config is still set to manual

Diagnosis:
Your renewal configuration still uses manual authentication, preventing automatic renewal.

Resolution:
Reissue the certificate using the DNS plugin, as in Step 4. Certbot will update the renewal config so future renewals use the correct method.

Renewed certificate not served by web server

Diagnosis:
certbot renew completes but your site still serves an old certificate.

Resolution:

  • Check for a deploy hook:

    • Inspect /etc/letsencrypt/renewal/example.com.conf for a renew_hook

    • Or list /etc/letsencrypt/renewal-hooks/deploy/:

      1. ls /etc/letsencrypt/renewal-hooks/deploy/
  • If absent, reload your web server manually:

    1. sudo systemctl reload nginx
  • To automate in the future, add a deploy hook as shown in Step 7.

  • See Nginx SSL Certificate and HTTPS Redirect Errors if the renewed files exist but the server still serves stale TLS material.

FAQs

1. Do I need separate certificates for the apex and the wildcard?

No. You should include both names in one request when you serve TLS on example.com and on *.example.com. Pass two -d flags as shown in Step 4. Let’s Encrypt treats them as separate SANs in the same certificate, and a single renewal job covers both.

2. Why does Certbot refuse HTTP validation for my wildcard request?

Let’s Encrypt only issues wildcards after a successful DNS-01 challenge. HTTP-01 cannot prove control of every possible subdomain, so the CA rejects wildcard requests that rely on HTTP alone.

3. How often do files under /etc/letsencrypt/live/ change?

Certbot refreshes symlinks whenever a renewal succeeds. Applications should always reference the live paths, not hard-copied files, so they pick up renewed material automatically. If your application caches the file descriptor at startup rather than reading the symlink on each connection, you may still need a reload hook.

4. Can I cover *.api.example.com in the same certificate as *.example.com?

Yes, you can include both in a single certificate by adding -d '*.api.example.com' alongside the other -d flags. Certbot will perform a DNS-01 challenge for each wildcard label, creating separate _acme-challenge TXT records: one at _acme-challenge.example.com and one at _acme-challenge.api.example.com. Keep in mind that each additional wildcard requires its own DNS API call during renewal.

Combining multiple wildcards into one certificate is supported, but separate certificates may simplify management and reduce blast radius.

5. Does a wildcard replace per-host certificates?

Wildcards reduce certificate count, yet they widen blast radius if a private key leaks. Many teams mix strategies, for example a wildcard on edge load balancers plus per-service certificates inside the mesh.

Conclusion

You now understand how Let’s Encrypt wildcard certificates with Certbot rely on DNS validation, how manual issuance differs from plugin-based automation, how to cover multi-domain and multi-level subdomain scenarios in a single certificate command, how to configure Nginx or Apache to serve TLS using the issued files, and how to verify and renew certificates without downtime surprises.

Continue learning with DigitalOcean

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Anish Singh Walia
Anish Singh Walia
Author
Sr Technical Content Strategist and Team Lead
See author profile

I help Businesses scale with AI x SEO x (authentic) Content that revives traffic and keeps leads flowing | 3,000,000+ Average monthly readers on Medium | Sr Technical Writer(Team Lead) @ DigitalOcean | Ex-Cloud Consultant @ AMEX | Ex-Site Reliability Engineer(DevOps)@Nutanix

Manikandan Kurup
Manikandan Kurup
Editor
Senior Technical Content Engineer I
See author profile

With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers.

Still looking for an answer?

Was this helpful?


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Step 1: Setup Pre-requisites. If you already have a droplet or a system then make sure your system has Python 2.7 or 3 and git installed on it. … Step 2: Setup Certbot. … Step 3: Generate The Wildcard SSL Certificate. … Step 4: Authenticate The Domain’s Ownership. … Step 5: Get The Certificate. … Step 6: Cross Verify The Certificate.

I followed the tutorial but ran into the following error (i replaced my original website with example.com below)

Encountered exception during recovery: certbot.errors.PluginError: Unable to determine base domain for example.com using names: ['example.com', 'com'].
Unable to determine base domain for example.com using names: ['example.com', 'com'].

Thanks for this – it’s very helpful. Quick question (I think): how will this work if I’ve already got an active lets encrypt certificate for the root domain? Will it simply overwrite/replace it and all will be well? Or am I flirting with disaster?

Hello there,

I followed this tutorial step by step and everything seems to work fine on the server side.

I run ‘sudo certbot certificates’ and it shows the certificates, but the browsers seems to be taken only the certificate for maindomain and www.maindomain, but no for the wildcard

I don’t know if this could be a problem, but I have created the main and the www with 'certbot –nginx’ and the wildcard with 'sudo certbot certonly \ –dns-digitalocean \ –dns-digitalocean-credentials ~/certbot-creds.ini \ -d *.domain.com’

I don’t know if there is a way to create only 1 certificate for the main, www and the wildcard in case that’s the problem. I’lll appreciate any leads, thanks in advance.

Hi,

In my case I receive Unable to determine base domain for betafox.net using names: [‘betafox.net’, ‘net’] error. I already have certbot SSL cert for main domain too, I only want wildcard for subdomains.

Thanks for this extremely detailed set of instructions.

What rights does the “single API token” described here need? Is it a “Personal Access Token” with full read and write?

and if I want to use www.*.domain.com ?

In Step 4 there should really be two -d statements:

-d ‘*.example.com’
-d ‘example.com

The certificate for the wildcard domains does not cover the base domain example.com. Could cause users to get a warning about the site’s security with a COMMON_NAME error.

October, 2025
The only thing you need to give the Personal Access Token access to is domain, so it can read, write, delete, and update TXT records for the DNS challenge. This token is the API token.

For Debian 13,

sudo apt install python3-pip -y
sudo pip3 install certbot-dns-digitalocean --break-system-packages
# < add your PAT/API key to /etc/letsencrypt/digitalocean.ini >
sudo certbot certonly --authenticator dns-digitalocean --dns-digitalocean-credentials /etc/letsencrypt/digitalocean.ini --dns-digitalocean-propagation-seconds 30 -d example.com -d "*.example.com"

No downtime for nginx . And certbot will update the certificate automatically every 90 days.

If you need to change the API key file location, edit /etc/letsencrypt/renewal/example.com.conf

Deleting an old entry: sudo certbot delete --cert-name example.com

Cheers

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Start building today

From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.

Dark mode is coming soon.