Certbot DNS-01 Challenge TXT Record Mismatch Troubleshooting on CentOS Stream / Rocky Linux
Resolve Certbot's DNS-01 challenge TXT record mismatch error on CentOS Stream or Rocky Linux systems, ensuring successful Let's Encrypt certificate issuance.
Resolve Certbot's DNS-01 challenge TXT record mismatch error on CentOS Stream or Rocky Linux systems, ensuring successful Let's Encrypt certificate issuance.
Certbot's DNS-01 challenge method is a powerful way to obtain or renew Let's Encrypt SSL certificates, especially for wildcard domains or when HTTP-01 challenges are not feasible (e.g., internal servers, complex network configurations). This method relies on Certbot creating a special _acme-challenge.<yourdomain> TXT record in your domain's DNS zone to prove ownership to the Let's Encrypt ACME server. When this process fails with a "TXT records mismatch" error, it indicates that while a TXT record was found, its value did not match what Let's Encrypt expected, thereby halting the certificate issuance or renewal. This guide provides expert-level troubleshooting steps specifically for CentOS Stream and Rocky Linux environments.
Symptom & Error Signature
When attempting to obtain or renew a Let's Encrypt SSL certificate using Certbot with the DNS-01 challenge method, you might encounter an error similar to the following in your terminal output:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer nginx
...
Performing the following challenges:
dns-01 challenge for example.com
Waiting for verification...
Challenge failed for domain example.com
dns-01 challenge for example.com failed
Cleaning up challenges
Some challenges have failed.
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: example.com
Type: dns
Detail: During secondary validation: The TXT record recently added to verify domain ownership did not match the expected value. Expected: "EXPECTED_TXT_VALUE_HERE" but got: "ANOTHER_TXT_VALUE_HERE"
To fix these errors, please make sure that your domain name was
entered correctly and that the DNS A/AAAA record(s) for that domain
contain the right IP address. Additionally, please check that the
nameservers are configured correctly and that the DNS TXT records are
propagated correctly.
This specific error clearly indicates that while a _acme-challenge.example.com TXT record was found by Let's Encrypt's validation servers, its value (ANOTHER_TXT_VALUE_HERE) did not match the value they expected (EXPECTED_TXT_VALUE_HERE). This means the DNS record was either incorrect, outdated, or not fully propagated at the time of validation.
Root Cause Analysis
The "TXT records mismatch" error typically stems from one or more of the following underlying issues:
- DNS Propagation Delays: This is the most common culprit. DNS changes, particularly newly created or updated TXT records, can take time (minutes to hours) to propagate across global DNS servers. Certbot might attempt to verify the record before it has fully propagated, leading to a mismatch (as an old or no record is seen).
- Incorrect or Stale DNS Records:
- Multiple
_acme-challengeTXT records: If previous failed Certbot attempts left behind old_acme-challengerecords, or if another service is also attempting DNS-01 challenges, Let's Encrypt might pick up the wrong record from the existing set. - Typographical Errors (Manual Challenge): If you are performing a manual DNS-01 challenge (i.e., Certbot prompts you to manually create the TXT record), a simple typo in the record value is a straightforward cause for the mismatch.
- Multiple
- Certbot DNS Plugin Misconfiguration (for Automated Challenges):
- Incorrect API Credentials: The credentials file (e.g.,
.inior.json) for your specific DNS provider plugin (e.g.,certbot-dns-cloudflare,certbot-dns-route53) might contain an incorrect API key, token, email, or zone ID, preventing Certbot from correctly creating or updating the TXT record. - Insufficient Permissions: The API credentials provided to Certbot might lack the necessary permissions within your DNS provider's system to modify TXT records for your domain.
- Rate Limiting by DNS Provider: Excessive API calls to your DNS provider within a short period might trigger temporary rate limits, causing record updates to fail silently or incompletely.
- Incorrect API Credentials: The credentials file (e.g.,
- DNS Caching Issues: Your local server's DNS resolver (
systemd-resolved,dnsmasq) or intermediate upstream DNS resolvers might be caching older DNS records, causing Certbot (or your manualdigqueries) to see an outdated state. - DNSSEC Misconfiguration: While less common for a direct "mismatch" of values, incorrectly configured DNSSEC can lead to validation failures, sometimes manifesting as issues with specific record types like TXT not being resolvable or causing
SERVFAILerrors. - Certbot or DNS Plugin Outdated: Bugs in older versions of Certbot or its DNS plugins could lead to issues interacting with DNS providers, generating incorrect challenge values, or handling the validation process correctly.
Step-by-Step Resolution
Follow these structured steps to diagnose and resolve the Certbot DNS-01 challenge TXT records mismatch on your CentOS Stream or Rocky Linux system.
1. Verify DNS Propagation and TXT Record Value
This is the most critical first step. You need to confirm what TXT record is actually visible to the world for your _acme-challenge subdomain.
Identify the expected value: Carefully examine the Certbot error message for the
Expected: "EXPECTED_TXT_VALUE_HERE"string. This is the exact value Let's Encrypt's validation server is looking for.Query DNS from your server: Use the
digutility to query public DNS resolvers directly, bypassing your local server's cache. Replaceexample.comwith your actual domain.# Query Google's public DNS resolver dig +short TXT _acme-challenge.example.com @8.8.8.8 # Query Cloudflare's public DNS resolver dig +short TXT _acme-challenge.example.com @1.1.1.1 # Query your domain's authoritative nameservers (replace ns1.yourdns.com with your actual nameserver) dig +short TXT _acme-challenge.example.com @ns1.yourdns.comExamine the output carefully:
- If you see no output or "NXDOMAIN", the record hasn't propagated or wasn't created by Certbot.
- If you see multiple TXT records, note all of their values.
- If you see a single TXT record, compare its value to the
EXPECTED_TXT_VALUE_HEREfrom Certbot's error.
Use Online DNS Checkers: Websites like
dnschecker.org,whatsmydns.net, ormxtoolbox.com/txt.aspxallow you to check DNS propagation globally. Enter_acme-challenge.example.comand select theTXTrecord type to see what different regions report.If the
digoutput or online checkers show a different value thanEXPECTED_TXT_VALUE_HERE, or if multiple_acme-challengeTXT records are present, this is the core issue. Proceed to step 4 and 5.
2. Increase Certbot's DNS Propagation Delay
If your DNS provider is known to be slow in propagating changes, Certbot might attempt validation before the record is globally visible. You can instruct Certbot to wait longer.
Identify your DNS plugin: For example,
dns-cloudflare,dns-route53,dns-digitalocean, etc.Add propagation delay: Append the
--dns-<plugin>-propagation-seconds <seconds>flag to your Certbot command. A value between30and120seconds (e.g.,--dns-cloudflare-propagation-seconds 60) is often sufficient.# Example for Cloudflare plugin, setting a 60-second delay for renewal sudo certbot renew --cert-name example.com --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini --dns-cloudflare-propagation-seconds 60 --nginx # or --apache, or omit if using --webroot / -d without installerFor Automatic Renewals: To make this propagation delay permanent for future automatic renewals, edit Certbot's global configuration file, typically located at
/etc/letsencrypt/cli.ini, or within the specific renewal configuration file for your domain (/etc/letsencrypt/renewal/example.com.conf).# Example content for /etc/letsencrypt/cli.ini or /etc/letsencrypt/renewal/example.com.conf dns-cloudflare-propagation-seconds = 60After updating the configuration, attempt renewal:
sudo certbot renew
3. Review Certbot DNS Plugin Configuration and Credentials
If you're using a Certbot DNS plugin for automated challenges, verify its setup meticulously.
Check Credentials File Permissions: The credentials file containing your DNS provider's API keys must be readable only by root to protect sensitive information.
sudo chmod 600 /etc/letsencrypt/cloudflare.iniIncorrect permissions (e.g., world-readable) will prevent Certbot from securely reading the file and could pose a significant security risk.
Verify Credential File Content: Open your credentials file (e.g.,
/etc/letsencrypt/cloudflare.ini,/etc/letsencrypt/route53.ini) and double-check the API key/token, email, zone ID, or other specific identifiers required by your DNS provider. Even a single character typo will cause an authentication failure.- Cloudflare Example (
cloudflare.ini):dns_cloudflare_email = [email protected] dns_cloudflare_api_key = YOUR_GLOBAL_API_KEY_OR_TOKEN_HERE - AWS Route53 Example (
route53.ini):dns_route53_aws_access_key_id = AKIA... dns_route53_aws_secret_access_key = YOUR_SECRET_ACCESS_KEY_HERE
Ensure you are using an API key/token with sufficient permissions to manage TXT records for the specific domain or zone you are trying to certify.
- Cloudflare Example (
Install/Update DNS Plugin: Ensure the relevant Certbot DNS plugin is installed and up-to-date.
# Install with dnf (if available in EPEL, often for core plugins like Nginx/Apache) sudo dnf install python3-certbot-nginx # or python3-certbot-apache # Install specific DNS plugin (often via pip, as dnf might not have all) sudo pip3 install --upgrade certbot-dns-cloudflare # or -dns-route53, etc.
4. Remove Stale _acme-challenge TXT Records
Multiple or outdated _acme-challenge TXT records for your domain can confuse Let's Encrypt's validation servers, leading to a mismatch or failure to find the correct record.
- Access your DNS provider's control panel: Log in to your domain registrar or DNS hosting provider (e.g., Cloudflare, AWS Route 53, GoDaddy, DigitalOcean).
- Locate your domain's DNS zone: Find the DNS management section for the domain experiencing the error.
- Identify and delete old
_acme-challengeTXT records: Look for any TXT records with the hostname_acme-challengeor_acme-challenge.wwwthat are not theEXPECTED_TXT_VALUE_HEREfrom your current Certbot attempt (or that seem orphaned from previous failed attempts). Delete them.Be extremely careful not to delete legitimate TXT records used for other services (e.g., SPF, DKIM, DMARC for email validation, or Google Site Verification). These records typically do not begin with
_acme-challenge. - Verify Deletion: Use
dig(as in Step 1) and online DNS checkers to confirm the old records have been removed and only the correct current record (if Certbot successfully placed one) or no_acme-challengerecord exists.
5. Update Certbot and Python Packages
An outdated Certbot client or its underlying Python dependencies might contain bugs or have compatibility issues with newer Let's Encrypt API changes or DNS provider APIs.
- Update Certbot (via DNF):
If you installed Certbot via Snap (common on CentOS Stream/Rocky Linux for newer versions):sudo dnf update certbot python3-certbot-nginx # or python3-certbot-apache, if installed this waysudo snap refresh certbot - Update DNS Plugins (via pip): If you installed DNS plugins via
pip, update them separately to ensure you have the latest bug fixes.sudo pip3 install --upgrade certbot certbot-dns-cloudflare # and any other installed DNS plugins
6. Clear Local DNS Cache (if applicable)
If your CentOS Stream/Rocky Linux server runs a local DNS caching service, it might be holding onto stale records, causing Certbot's local lookups to be incorrect.
- Restart
systemd-resolved:sudo systemctl restart systemd-resolved - Restart
dnsmasq(if installed and used):sudo systemctl restart dnsmasq
7. Check for DNSSEC Issues
While less common for a direct "mismatch," improperly configured DNSSEC can cause validation failures by making DNS records unresolvable or untrustworthy.
- DNSSEC diagnostic tools: Visit
dnsviz.netorzonemaster.net. Enter your domain name and check for any DNSSEC errors or warnings. Common issues include incorrect DS records at your registrar or expired DNSKEYs. - Consult your DNS provider: If DNSSEC errors are identified, your DNS provider or domain registrar can help diagnose and correct DS record issues. If not managed carefully, it might be better to temporarily disable DNSSEC at your registrar while troubleshooting, then re-enable once Certbot is working.
8. Retest the Certbot Challenge
After carefully performing the above troubleshooting steps, reattempt the Certbot challenge.
For existing certificates (renewal):
sudo certbot renewIf
certbot renewhas failed multiple times, you might need to force a new renewal attempt:sudo certbot renew --force-renewalUse
--force-renewalsparingly. Repeated failures with--force-renewalcan quickly trigger Let's Encrypt rate limits (e.g., 5 failures per week for a given domain), temporarily blocking further certificate issuance for your domain. Use--dry-runfirst (see below).For new certificates:
sudo certbot certonly --dns-cloudflare -d example.com -d www.example.com --email [email protected] --agree-tos --no-eff-email --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini --nginx # or --apacheRemember to replace
dns-cloudflarewith your actual DNS plugin and adjust domain names and email as necessary.Before a live run, always test your configuration with
--dry-runto ensure all parameters are correct and avoid hitting rate limits:sudo certbot renew --dry-run # Or for a new certificate: sudo certbot certonly --dns-cloudflare -d example.com --dry-run --debug # Add relevant optionsThe
--debugflag can provide more verbose output in/var/log/letsencrypt/letsencrypt.log, which may offer additional clues.
By systematically working through these expert-level steps, you should be able to identify and resolve the Certbot DNS-01 challenge TXT records mismatch, allowing you to successfully issue or renew your Let's Encrypt SSL certificates on CentOS Stream or Rocky Linux.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.