Certbot ACME Directory Verification Failed: Server Connection Errors on CentOS Stream/Rocky Linux
Troubleshoot Certbot 'ACME directory verification failed server connection' on CentOS Stream/Rocky Linux, covering firewalls, DNS, web server, and network issues.
Troubleshoot Certbot 'ACME directory verification failed server connection' on CentOS Stream/Rocky Linux, covering firewalls, DNS, web server, and network issues.
Introduction
Obtaining or renewing SSL/TLS certificates with Certbot and Let's Encrypt is usually a straightforward process. However, you may encounter the cryptic error "ACME directory verification failed server connection" which indicates that the Let's Encrypt ACME server could not establish a connection to your server to perform the necessary domain validation. This guide will walk you through diagnosing and resolving these connection issues on CentOS Stream and Rocky Linux environments, ensuring your websites remain secure with valid certificates.
Symptom & Error Signature
When running certbot to obtain or renew a certificate, you'll typically see an error similar to this in your terminal output:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Requesting a certificate for yourdomain.com and www.yourdomain.com
Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
Domain: yourdomain.com
Type: connection
Detail: During secondary validation: 203.0.113.1: Fetching http://yourdomain.com/.well-known/acme-challenge/YOUR_CHALLENGE_TOKEN: Connection refused
Domain: www.yourdomain.com
Type: connection
Detail: During secondary validation: 203.0.113.1: Fetching http://www.yourdomain.com/.well-known/acme-challenge/ANOTHER_CHALLENGE_TOKEN: Connection timed out
Hint: The Certificate Authority failed to download the challenge files. Ensure that your webserver is running and that it is accessible from the internet.
Some challenges have failed.
The key indicators are Type: connection, Connection refused, or Connection timed out when fetching the ACME challenge file (.well-known/acme-challenge/). This directly points to an issue preventing the Let's Encrypt validation server from reaching your web server.
Root Cause Analysis
The "ACME directory verification failed server connection" error fundamentally means the Let's Encrypt validation servers cannot communicate with your host on the required port (typically 80 for http-01 challenges or 443 for tls-alpn-01 challenges). The underlying causes can vary:
- Firewall Restrictions: This is the most common culprit. Your server's local firewall (
firewalld,iptables) or an external cloud/network firewall (security groups, ACLs) is blocking incoming connections on ports 80 and/or 443. - Incorrect DNS Resolution: The domain's A/AAAA records might point to the wrong IP address, or DNS changes haven't fully propagated. The ACME server attempts to connect to the IP address resolved for your domain.
- Web Server Issues:
- The web server (Nginx, Apache) is not running or has crashed.
- The web server is not configured to listen on port 80 (or 443).
- The web server's virtual host configuration is incorrect, preventing it from serving content from the
.well-known/acme-challengedirectory. - If using the
webrootauthenticator, the specified webroot path is incorrect or inaccessible.
- Network Connectivity Problems: Less common for inbound connections, but potential underlying network issues on the server itself, or routing problems preventing external access.
- SELinux Interference: While less frequent for basic HTTP-01 challenges, SELinux policies could potentially prevent the web server from accessing certain files or directories required by Certbot, or even bind to ports under strict configurations.
- CDN/Reverse Proxy Misconfiguration: If your domain uses a CDN (like Cloudflare) or a reverse proxy, it might be intercepting or caching the ACME challenge requests, preventing them from reaching your origin server.
- Rate Limiting by Let's Encrypt: If you've attempted certificate issuance or renewal too many times within a short period, Let's Encrypt might temporarily block requests from your IP, although this typically results in a different error message (
too many requests).
Step-by-Step Resolution
Follow these steps meticulously to diagnose and resolve the connection failure.
1. Verify Basic Network Connectivity and DNS Resolution
First, ensure your server can reach the internet and that your domain resolves correctly.
Check Outbound Connectivity:
ping -c 4 8.8.8.8 curl -v https://acme-v02.api.letsencrypt.org/directoryIf
pingfails, you have a fundamental network issue. Ifcurlfails, your server might have outbound firewall issues or general connectivity problems to the Let's Encrypt API.Verify DNS Resolution: Confirm that your domain's A/AAAA records point to the correct public IP address of your server. Use an external DNS lookup tool (e.g.,
digfrom another machine, or a web-based tool) as well as locally.# On your server dig A +short yourdomain.com dig AAAA +short yourdomain.com # Example for external check (from a different machine or online tool) dig @8.8.8.8 A yourdomain.comEnsure the IP address returned matches your server's public IP. DNS changes can take time to propagate globally.
2. Check and Configure Server Firewall (Firewalld)
This is the most common fix. CentOS Stream and Rocky Linux use firewalld by default.
Check Firewall Status:
sudo firewall-cmd --state sudo firewall-cmd --list-all --zone=publicEnsure
firewalldis running and verify that serviceshttp(port 80) andhttps(port 443) are listed as allowed in thepubliczone.Open Required Ports: If
httporhttpsare not listed, add them. Let's Encrypt typically uses port 80 for thehttp-01challenge and port 443 fortls-alpn-01(if applicable).sudo firewall-cmd --zone=public --add-service=http --permanent sudo firewall-cmd --zone=public --add-service=https --permanent sudo firewall-cmd --reloadAfter running these commands, always run
sudo firewall-cmd --reloadto apply the changes without dropping existing connections. Verify withsudo firewall-cmd --list-all --zone=public.Cloud Provider Firewalls: If your server is hosted on a cloud platform (AWS EC2, Google Cloud, Azure, DigitalOcean), check its security group rules or network firewall settings. These often override or complement your server's local firewall. Ensure inbound TCP traffic on ports 80 and 443 is allowed from anywhere (
0.0.0.0/0).
3. Inspect Web Server Status and Configuration
Ensure your web server is running and correctly configured to serve the ACME challenge.
Check Web Server Status:
sudo systemctl status nginx # Or apache2 for ApacheVerify the output shows
active (running). If not, start it:sudo systemctl start nginx # Or apache2 sudo systemctl enable nginx # To ensure it starts on bootVerify Web Server Listeners: Ensure your web server is configured to listen on port 80. For Nginx, check
/etc/nginx/nginx.confand your virtual host files (e.g.,/etc/nginx/conf.d/yourdomain.com.conf). Look forlisten 80;. For Apache, check/etc/httpd/conf/httpd.confand virtual host files (e.g.,/etc/httpd/conf.d/yourdomain.com.conf). Look forListen 80.Test Nginx configuration:
sudo nginx -tTest Apache configuration:
sudo apachectl configtestResolve any reported syntax errors.
Test ACME Challenge Path: If your web server is running and accessible externally, you should be able to create a dummy file and access it. Create a test file:
sudo mkdir -p /var/www/html/.well-known/acme-challenge/ echo "test" | sudo tee /var/www/html/.well-known/acme-challenge/testfileThen, try to access
http://yourdomain.com/.well-known/acme-challenge/testfilefrom your browser orcurlfrom an external machine. If this fails, your web server or its configuration for the webroot is the issue. If you use a different webroot (e.g.,/usr/share/nginx/html), adjust the path accordingly.Certbot's
webrootauthenticator requires the web server to correctly serve files from the specifiedwebroot-path. If using thenginxorapacheauthenticators, Certbot attempts to temporarily modify your server config.
4. SELinux Policy Review
SELinux can sometimes block web server access, leading to "permission denied" errors when Certbot tries to write or the web server tries to read challenge files.
Check SELinux Status:
sestatusIf SELinux is
enforcing, check the audit logs for denials.sudo ausearch -c httpd -ts todayLook for
AVCdenials related tohttpd(Apache) ornginx.Temporary Test (Not Recommended for Production): If you suspect SELinux, you can temporarily set it to
permissivemode to confirm:sudo setenforce 0 # Try running certbot again sudo certbot renew --dry-run sudo setenforce 1 # Re-enable enforcing modeDo NOT leave SELinux in
permissiveordisabledmode in a production environment. If this fixes the issue, identify the specific SELinux policy that needs adjustment (e.g., usingaudit2allow) rather than disabling it.Common SELinux Booleans for Web Servers: Sometimes, specific booleans might be needed, though less common for basic
.well-knownaccess.sudo getsebool -a | grep httpd # Example: If your webroot is on an unusual path, you might need: # sudo setsebool -P httpd_enable_homedirs on
5. Check for CDN/Reverse Proxy Interference
If your domain is behind a CDN (like Cloudflare) or a reverse proxy, the Let's Encrypt validator will connect to the CDN/proxy's IP, not your origin server.
Cloudflare Specifics: If using Cloudflare, ensure your DNS records for
yourdomain.comandwww.yourdomain.comhave the "Proxy status" set to "DNS only" (the cloud icon should be grey, not orange) during the Certbot validation process. This allows Let's Encrypt to directly connect to your server. After successful validation, you can re-enable the proxy if desired. Alternatively, forhttp-01challenges, you can set up a Cloudflare Page Rule to bypass caching/security for the/.well-known/acme-challenge/*path.Other Reverse Proxies: Ensure your reverse proxy is correctly configured to forward requests for
/.well-known/acme-challenge/to your actual web server without modification or caching.
6. Increase Logging and Debugging
If the problem persists, increase Certbot's verbosity and examine system logs.
Certbot Debug Output:
sudo certbot renew --dry-run -v sudo certbot certonly --webroot -w /var/www/html -d yourdomain.com -d www.yourdomain.com --dry-run -vThe
-v(verbose) flag will provide more detailed output.--dry-runallows you to test the process without hitting Let's Encrypt's rate limits.Review System Logs:
sudo journalctl -u nginx --since "1 hour ago" sudo journalctl -u httpd --since "1 hour ago" sudo tail -f /var/log/letsencrypt/letsencrypt.logLook for any errors around the time you tried to run Certbot. This can give clues about web server issues or permission problems.
7. Try Different Certbot Authenticator
If the webroot authenticator struggles, consider the nginx or apache authenticators if you use those web servers directly, as they can temporarily modify configurations to handle challenges.
Using Nginx Authenticator:
sudo certbot renew --nginx --dry-run # Or for initial cert sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com --dry-runEnsure the
python3-certbot-nginxpackage is installed (sudo dnf install python3-certbot-nginx).Using Apache Authenticator:
sudo certbot renew --apache --dry-run # Or for initial cert sudo certbot --apache -d yourdomain.com -d www.yourdomain.com --dry-runEnsure the
python3-certbot-apachepackage is installed (sudo dnf install python3-certbot-apache).
By systematically working through these steps, you should be able to identify and resolve the root cause of your Certbot ACME directory verification failure on CentOS Stream and Rocky Linux. Most commonly, it boils down to an improperly configured firewall or an inactive/misconfigured web server.