How to Fix cURL Error 28: Connection Timed Out in WordPress?
Problem Statement & Impact
cURL Error 28 manifests in WordPress when an outbound HTTP request initiated via the PHP cURL extension fails to complete within the designated time threshold. Within the WordPress execution lifecycle, this error disrupts the Site Health diagnostic utility, breaks background Action Scheduler routines, prevents automated core, theme, and plugin updates, and disables vital REST API communications. Affected environments span the entire WordPress stack, including self-hosted single instances, large-scale multisite networks, containerized Kubernetes deployments, and traditional LEMP/LAMP cloud server architectures running on AWS, Google Cloud Platform, or DigitalOcean.
The business and security consequences of inaction are severe. When administrative requests time out, security plugins cannot fetch threat intelligence feeds, Web Application Firewall (WAF) signature updates fail, and vulnerability scanners cannot verify core integrity hashes. Furthermore, payment gateways relying on webhook communications or direct API calls to process transactions will encounter silent failures, directly impacting revenue generation. Content delivery networks (CDNs) and single sign-on (SSO) providers relying on OAuth token exchanges via the WordPress REST API will similarly break, resulting in degraded user experience and broken site functionality.
Root Cause Analysis & Architecture
To understand cURL Error 28, one must analyze the interaction between the WordPress application layer, the PHP process manager (PHP-FPM), the underlying libcurl library, and the operating system’s networking stack. When WordPress executes a function like wp_remote_get() or wp_remote_post(), it delegates the request to the HTTP Transport API, which utilizes the PHP cURL extension by default. The libcurl library then opens a TCP socket, performs a DNS lookup, executes the TLS handshake, and waits for the remote server to return HTTP headers and body content.
Chat with an engineer on WhatsApp within 15 minutes.
The timeout behavior is governed by two primary libcurl options translated from WordPress arguments: CURLOPT_TIMEOUT (the maximum time in seconds that the entire transfer is allowed to take) and CURLOPT_CONNECTTIMEOUT (the maximum time allowed for the connection phase). In default WordPress configurations, the general timeout is frequently set to 5 seconds for loopback requests (such as REST API calls to itself). If any bottleneck interrupts this transmission chain, libcurl terminates the connection and returns error code 28: CURLE_OPERATION_TIMEDOUT.
Primary Failure Vectors
- Loopback Request Failures: WordPress attempts to communicate with its own REST API (`/wp-json/`) during Site Health checks or block editor saving. If local DNS resolution fails, or if server-level web application firewalls (e.g., ModSecurity) flag the internal traffic as suspicious, the connection drops.
- DNS Resolution Latency: If the nameservers configured in `/etc/resolv.conf` (such as a local BIND instance or unresponsive upstream ISP resolvers) take longer than the connection timeout to resolve domain names to IP addresses, the request fails before packet transmission even begins.
- Stateful Firewall and NAT Traversal Bottlenecks: Stateful firewalls (such as iptables, UFW, or cloud security groups) tracking TCP connection tables may drop packets if connection tracking tables are saturated, or if outbound ephemeral ports are exhausted.
- PHP-FPM Process Starvation: When all available PHP-FPM child processes are occupied executing long-running database queries or heavy background tasks, asynchronous or synchronous loopback requests queue up and eventually time out waiting for an available execution thread.
Step-by-Step Implementation & Remediation Guide
Resolving cURL Error 28 permanently requires a systematic approach targeting the operating system, network routing, PHP configuration, and WordPress application layers. Execute the following procedures sequentially.
Step 1: Diagnose and Fix Loopback Communication via WP-CLI
First, use WP-CLI to test whether your server can successfully execute HTTP requests to its own domain. Run the following command on your server terminal:
wp eval 'print_r( wp_remote_get( home_url( "/wp-json/" ) ) );' --path=/var/www/html
If this command returns a timeout error or a non-200 HTTP status code, your server is experiencing internal loopback restrictions. Inspect the server’s hosts file to ensure the domain correctly resolves to the local loopback interface or the public IP address:
cat /etc/hosts
If necessary, add an explicit DNS entry mapping your domain to your server’s primary IP address to bypass external DNS lookup overhead during internal API calls.
Step 2: Optimize cURL Timeout Thresholds in WordPress
If your external API integrations (such as payment gateways or translation services) legitimately require more than the default 5 seconds to respond, you can programmatically increase the timeout duration. Add the following filter to your theme’s functions.php file or a custom site-specific plugin:
add_filter( 'http_request_timeout', function( $handle ) {
// Increase timeout to 15 seconds for all HTTP requests
return 15;
});
For more granular control over specific external requests, you can target individual cURL handles using the http_api_curl action hook:
add_action( 'http_api_curl', function( $handle, $r, $url ) {
// Target a specific slow external API
if ( strpos( $url, 'api.example-slow-service.com' ) !== false ) {
curl_setopt( $handle, CURLOPT_TIMEOUT, 30 );
curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, 10 );
}
}, 10, 3 );
Step 3: Update and Configure DNS Resolvers
Faulty DNS resolution is a frequent catalyst for cURL timeouts. Replace your server’s default DNS resolvers with high-performance public resolvers (Cloudflare and Google). Edit your netplan configuration or directly update /etc/resolv.conf:
sudo nano /etc/systemd/resolved.conf
Uncomment and modify the DNS parameter lines:
DNS=1.1.1.1 8.8.8.8 2606:4700:4700::1111
FallbackDNS=8.8.4.4
Restart the systemd-resolved service to apply the configuration changes immediately:
sudo systemctl restart systemd-resolved
Step 4: Audit Server Firewall and Outbound Port Rules
Ensure your firewall permits outbound traffic on standard ports 80 (HTTP) and 443 (HTTPS). If you are using UFW on an Ubuntu/Debian server, verify the rules with:
sudo ufw status verbose
If restrictive outbound rules are enforced, explicitly allow outbound connections for your web server daemon:
sudo ufw allow out 80/tcp
sudo ufw allow out 443/tcp
sudo ufw reload
For enterprise environments utilizing iptables or cloud-based security groups (such as AWS Security Groups), check that stateful inspection is not dropping established outbound packets due to aggressive connection-tracking timeout values.
Step 5: Inspect and Upgrade System Libraries
Outdated versions of the NSS (Network Security Services) or OpenSSL libraries linked to cURL can cause TLS handshake freezes. Verify your current cURL and OpenSSL versions via CLI:
php -r 'print_r( curl_version() );'
Update your operating system’s networking and SSL packages to their latest stable releases using your package manager:
sudo apt-get update && sudo apt-get install --only-upgrade curl libcurl4 openssl php-curl
Production Hardening & Edge Cases
Implementing fixes in a staging environment before pushing to production is critical to avoid unintended regressions. When modifying PHP-FPM or Nginx/Apache timeout directives, consider the performance trade-offs. Setting timeouts too high can cause web server worker processes to hang indefinitely when an external API becomes completely unresponsive, eventually exhausting all available worker threads and causing a total site outage.
For high-traffic production environments, configure Nginx proxy timeouts to align logically with PHP execution limits. In your Nginx server block configuration, verify or adjust the following parameters:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_read_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_connect_timeout 60s;
}
Similarly, for Apache servers utilizing PHP-FPM via mod_proxy_fcgi, adjust the timeout directive in your virtual host configuration:
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
ProxyTimeout 60
</FilesMatch>
Caching and Reverse Proxy Conflicts: If you utilize an aggressive full-page caching layer (such as Varnish or Nginx micro-caching), ensure that REST API endpoints and loopback requests are explicitly excluded from caching rules. Caching loopback requests can cause WordPress to read stale responses, leading to persistent authorization failures and cron execution halts.
Diagnostic Verification & Checklist
After executing the remediation steps, systematically verify system health using the diagnostic matrix below. Monitor server error logs and HTTP response codes to ensure complete resolution.
| Diagnostic Check | Command / Tool | Expected Result |
|---|---|---|
| WordPress Site Health | Dashboard > Tools > Site Health | Zero cURL or loopback communication errors reported. |
| WP-CLI REST API Test | wp eval 'print_r( wp_remote_get( home_url( "/wp-json/" ) ) );' |
HTTP status code `200 OK` with valid JSON response payload. |
| DNS Resolution Speed | dig @1.1.1.1 yourdomain.com +noall +answer |
Resolution time under 50ms with correct server IP address. |
| External API Connectivity | curl -I https://api.wordpress.org |
HTTP/2 200 response received within 2 seconds. |
| PHP cURL Extension Status | php -m | grep curl |
Extension explicitly loaded without dependency warnings. |
Log File Locations to Monitor
- Nginx Error Log:
/var/log/nginx/error.log(Check for upstream timed out errors). - Apache Error Log:
/var/log/apache2/error.log(Check for proxy FCGI timeout entries). - PHP-FPM Error Log:
/var/log/php8.2-fpm.log(Check for slow log traces and child process exhaustion). - WordPress Debug Log:
/wp-content/debug.log(Ensure `WP_DEBUG_LOG` is enabled during testing to catch HTTP API transport errors).
Is Your Website Fast & Secure?
Run an instant scan for security vulnerabilities, bloated plugins, and TTFB latency.
Need Help Securing or Speeding Up Your Site?
Get 24/7 proactive security WAF, daily cloud backups, and sub-second speed optimization from ₹3,470/mo.