Skip to main content

Let's Encrypt Wildcard: Auto-Renewal for Subdomains

Security · 19.04.2026 · 6 min read
Illustration for “Let's Encrypt Wildcard: Auto-Renewal for Subdomains”

A Wildcard SSL certificate (*.example.com) covers all subdomains at one level. Let's Encrypt issues them for free, but only via DNS verification (not HTTP). This requires either manually adding a TXT record or automating it through a DNS API.

Obtaining a Wildcard via Certbot (manual DNS)

certbot certonly --manual --preferred-challenges=dns   -d example.com -d "*.example.com"

# Certbot will ask you to add a TXT record:
# _acme-challenge.example.com → "value"
# Add the record in your DNS panel and press Enter
pip install certbot-dns-cloudflare

# Create a file with the Cloudflare API token
mkdir -p /etc/letsencrypt/cloudflare
cat > /etc/letsencrypt/cloudflare/credentials.ini << 'EOF'
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
chmod 600 /etc/letsencrypt/cloudflare/credentials.ini

# Obtain the Wildcard certificate
certbot certonly   --dns-cloudflare   --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini   -d example.com   -d "*.example.com"   --preferred-challenges dns-01

Setting up auto-renewal

systemctl status certbot.timer
systemctl list-timers | grep certbot

# Test renewal (no actual update)
certbot renew --dry-run

# Force renewal
certbot renew --force-renewal

# View all certificates
certbot certificates

acme.sh as an alternative to Certbot

>curl https://get.acme.sh | sh -s email=admin@example.com

export CF_Token="YOUR_CLOUDFLARE_API_TOKEN"
acme.sh --issue --dns dns_cf -d example.com -d "*.example.com"

acme.sh --install-cert -d example.com   --key-file /etc/ssl/example.com.key   --fullchain-file /etc/ssl/example.com.pem   --reloadcmd "systemctl reload nginx"

Monitoring certificate expiration

openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>&1 | grep "notAfter"
certbot certificates | grep -E "Expiry|Domains"
Expiration notifications: Let's Encrypt automatically sends an email 30, 20, and 10 days before expiration. Make sure the email address used to register certbot is up to date.
Let's Encrypt limits: 50 certificates per domain per week, 5 duplicate certificates per week, 100 subdomains per certificate. For production, use the staging environment when testing: --staging.

Common Errors Issuing a Wildcard

MessageWhat it means
Incorrect TXT record found at _acme-challenge.example.comDNS hasn't updated yet (old TTL) or the record was added to the wrong zone
urn:ietf:params:acme:error:rateLimitedThe weekly Let's Encrypt request limit for the domain was exceeded — wait for the reset window
Cloudflare API error: Invalid request headersA Global API Key is used instead of a scoped API Token, or the token lacks Zone:DNS:Edit rights
certbot: command not found after installingThe package was installed with a different manager (snap instead of apt), or PATH wasn't refreshed in the current shell session

Certbot vs acme.sh: Which to Choose

CriterionCertbotacme.sh
DependenciesPython and system packagesJust Bash and curl
Account key storage/etc/letsencryptIn the user's home directory
DNS provider pluginsOfficial and third-party pip packagesBuilt-in shell scripts for dozens of DNS APIs
Install privilegesUsually requires rootCan run without root

When You Don't Need a Wildcard Certificate

  • The server only has 1-2 subdomains — a regular SAN certificate for the specific names is simpler and faster to issue
  • The domain's DNS is managed by a third party with no API access — manually renewing the TXT record every 90 days becomes ongoing chore
  • A proxy like Cloudflare already terminates TLS in front of the origin for visitors — an Origin certificate between Cloudflare and the server is often enough
  • You need an EV or OV certificate with organization verification — Let's Encrypt only issues DV certificates

Verifying Auto-Renewal

# Logs of recent renewal attempts
journalctl -u certbot.timer --since "7 days ago"

# Freshness of the TXT record as seen by external DNS
dig TXT _acme-challenge.example.com +short @1.1.1.1

If journalctl shows successful timer runs but the certificate didn't renew, check the history with certbot certificates and compare the Expiry date to today. Related: SSL and Certbot on Nginx and Cloudflare's Origin certificate as an alternative for sites behind a proxy.

Storing the API Token Safely

The file holding the Cloudflare API token used in the examples above lives on the server's disk and needs protecting just like the certificate's private key. A token with Zone:DNS:Edit rights can manage every DNS record in the zone — if it leaks, an attacker can not only read records but rewrite them, including the mail MX records. Scope the token to a specific zone when creating it in the Cloudflare dashboard, rather than issuing one with access to every zone on the account at once.

Frequently asked questions

Will auto-renewal work if the wildcard certificate was obtained through the manual DNS challenge instead of the Cloudflare API?

No, the manual mode requires manually adding a new TXT record on every renewal, so certbot's automatic timer can't pass verification without a person involved. True auto-renewal needs a method that adds and removes the TXT record in DNS by itself — a plugin like dns-cloudflare or a similar script in acme.sh, not the manual challenge mode.

How do I avoid hitting Let's Encrypt's rate limit while testing the setup?

Test certificate issuance with the staging flag, which uses a separate test environment with its own, much looser limits and doesn't consume any of the production request quota. Only switch to the real production issuance once the whole process has gone through staging without errors — otherwise failed attempts against production quickly run into the weekly limit.

Is it safer to have separate certificates for each subdomain instead of one wildcard?

From a private-key standpoint, the risk is arguably higher with a wildcard: the same private key covers every subdomain at once, and leaking it on any one of the servers where it's installed compromises protection for all of them simultaneously. Separate per-subdomain certificates isolate that risk — compromising one key doesn't touch the rest of the subdomains.

Can I use Certbot and acme.sh at the same time on one server?

Technically yes, but it's better to pick one: both tools independently issue and renew certificates, store their account keys in different places, and have no awareness of each other, so it's easy to end up confused about which certificate is actually wired into the web server's config. It's simpler to keep a single auto-renewal tool per domain.

Was this article helpful?
← Back to Knowledge Base Ask Support