Skip to main content

DNS Challenge for SSL: Wildcard Let's Encrypt Certificate

Domains · 19.04.2026 · 4 min read
Illustration for “DNS Challenge for SSL: Wildcard Let's Encrypt Certificate”

The ordinary HTTP challenge for Let's Encrypt does not support Wildcard certificates (*.example.com). A Wildcard needs the DNS-01 challenge — validation through a TXT record in DNS.

How the DNS-01 Challenge Works

  1. Certbot requests a certificate from Let's Encrypt
  2. Let's Encrypt issues a random token
  3. Certbot asks you to add a TXT record: _acme-challenge.example.com
  4. Let's Encrypt verifies the TXT record over DNS
  5. The certificate is issued

Manually with certbot

# Request a Wildcard certificate
certbot certonly --manual --preferred-challenges dns   -d "*.example.com" -d "example.com"

# Certbot will show the TXT record to add:
# _acme-challenge.example.com. 300 IN TXT "TOKEN"

# Add the record to DNS, then press Enter
# The certificate will be in /etc/letsencrypt/live/example.com/

Automatically with acme.sh + Cloudflare API

># Install acme.sh
curl https://get.acme.sh | sh

# Configure the Cloudflare API
export CF_Token="YOUR_CLOUDFLARE_API_TOKEN"
export CF_Account_ID="YOUR_ACCOUNT_ID"

# Issue the Wildcard certificate
~/.acme.sh/acme.sh --issue   --dns dns_cf   -d "*.example.com"   -d "example.com"   --keylength ec-256

# Install it into Nginx
~/.acme.sh/acme.sh --install-cert   -d "*.example.com"   --key-file /etc/nginx/ssl/example.key   --fullchain-file /etc/nginx/ssl/example.crt   --reloadcmd "systemctl reload nginx"

DNS Providers Supported by acme.sh

acme.sh supports automatic renewal through the API of more than 100 DNS providers: Cloudflare, Route 53, DigitalOcean, Namecheap, Google Cloud DNS and others.

💡 Wildcard + cron: Set up auto-renewal via cron — acme.sh does this for you at install time. Let's Encrypt certificates are valid for 90 days, so they need renewing every 60 days.
⚠️ Manual DNS challenge: With the manual procedure the certificate cannot be renewed automatically — you would have to repeat the process every 90 days. Use the API integration to automate it.

An Alternative to acme.sh: certbot with the certbot-dns-cloudflare Plugin

If certbot feels more familiar than acme.sh, DNS-01 for Cloudflare is also available through an official plugin — no need to hand-write a script with curl calls to the API.

# Install the plugin
apt install python3-certbot-dns-cloudflare -y

# Token file, permissions must be 600
echo "dns_cloudflare_api_token = YOUR_TOKEN" > /root/.secrets/cloudflare.ini
chmod 600 /root/.secrets/cloudflare.ini

# Issue the Wildcard certificate
certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d "*.example.com" -d "example.com"

certbot adds and removes the TXT record through the API on its own, waits for propagation, and can renew the certificate via cron without any extra scripts on top of acme.sh.

Common DNS-01 Challenge Errors

MessageCause
DNS problem: NXDOMAIN looking up TXTThe TXT record was never added, or it was added in the zone of a different domain or subdomain
DNS problem: query timed outThe zone's TTL is too high, or the local resolver has not seen the change yet — wait for the record to propagate
CF_Token: command not foundThe CF_Token and CF_Account_ID environment variables were not exported in the current session — a missing export, or the script ran from cron without them
Multiple validation errors: unauthorizedAn old TXT record from a previous attempt was never removed; DNS returned several _acme-challenge records at once, and Let's Encrypt only checks one
Verify error with a correct TXT recordThe record has not yet propagated to all authoritative NS servers — acme.sh did not wait long enough; increase --dnssleep

When DNS Challenge Is Not the Right Tool

  • You only need a certificate for one specific subdomain, not a wildcard — the plain HTTP-01 challenge via certbot --nginx is simpler and needs no DNS API access
  • DNS is managed by a registrar with no API, or the API is unsupported by acme.sh — manually updating the TXT record before every renewal is impractical and risks missing the deadline
  • The certificate must be issued instantly, within seconds — DNS-01 always waits for the record to propagate, at least tens of seconds and often minutes
  • You need a certificate for a bare IP address — Let's Encrypt does not issue certificates for IPs through either the HTTP or the DNS challenge

Verifying the Result

Before pressing Enter in certbot or waiting on acme.sh, confirm the record is actually visible to public DNS — it saves time on repeated attempts. Renewal and auto-renewal details are covered in the articles on configuring certbot for a wildcard and on Let's Encrypt auto-renewal.

# Confirm the TXT record is actually visible to public DNS
dig +short TXT _acme-challenge.example.com @8.8.8.8

# Check the expiration date of an already issued certificate
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -enddate
Was this article helpful?
← Back to Knowledge Base Ask Support