Fix Smush “cURL error 28: Operation timed out” During Bulk Optimize

Running Bulk Smush and getting “cURL error 28: Operation timed out”? That means WordPress couldn’t complete a remote request fast enough while Smush tried to process images. Below is a tight, copy-paste playbook to diagnose connectivity, raise timeouts, and nudge Smush to complete large queues reliably.

Smush keeps failing with “cURL error 28: Operation timed out” when I bulk optimize images. How do I fix this?

Why this happens

Smush sends images through a remote service to compress them. If your server can’t reach that service quickly enough or a firewall/proxy/DNS hiccup slows the request, WordPress hits its HTTP timeout and throws cURL error 28 (“Operation timed out”).

Quick checks (2 minutes)

  1. Retry a single image (Media Library → Smush one attachment). If single works but bulk fails, you likely need a timeout increase or smaller batches.
  2. Temporarily pause security/WAF plugins (Wordfence, Sucuri, NinjaFirewall, server WAF) and test Bulk Smush again.
  3. Check server load (CPU/RAM). Overloaded shared hosts commonly time out remote calls.

Fix #1: Allow outbound requests (firewall / WAF / host)

Smush relies on external HTTP(S) calls. Ask your host to allowlist WPMU DEV/Smush endpoints and verify outbound connections are permitted from PHP/cURL. If you’ve set WordPress to block external calls, make sure Smush’s domains are allowed:

/* wp-config.php */
define('WP_HTTP_BLOCK_EXTERNAL', false);
// If you must keep it true for policy reasons:
define('WP_HTTP_BLOCK_EXTERNAL', true);
define('WP_ACCESSIBLE_HOSTS', '*.wpmudev.com, wpmudev.com');

Tip: If you use a server firewall (CSF, UFW) or hosting “outbound filtering,” ensure ports 80/443 are open and outbound DNS resolves quickly.

Fix #2: Raise the WordPress HTTP timeout (copy-paste)

On busy/latent networks, the default HTTP timeout can be too low for large queues. Raise it globally or just for remote requests:

/* mu-plugins/http-timeout.php */
<?php
/**
 * Raise HTTP timeouts for remote requests (helps Bulk Smush).
 */
add_filter('http_request_timeout', function ($timeout) {
    return max(30, (int) $timeout); // 30–60s is common
});
add_filter('http_request_args', function ($args) {
    $args['timeout'] = max(30, isset($args['timeout']) ? (int)$args['timeout'] : 0);
    return $args;
});

Fix #3: Force IPv4 if IPv6 causes slow resolves

Some hosts have flaky IPv6 resolution. Force cURL to use IPv4 for WordPress HTTP calls:

/* mu-plugins/http-ipv4.php */
<?php
/**
 * Force IPv4 to avoid slow IPv6 DNS paths (cURL 28 timeouts).
 */
add_action('http_api_curl', function ($handle) {
    if (defined('CURL_IPRESOLVE_V4')) {
        curl_setopt($handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
    }
});

Fix #4: Ensure background processing actually runs

  • WP-Cron enabled? If you’ve disabled it, Smush/background tasks may stall. Re-enable or run a real cron that calls wp-cron.php frequently.
/* wp-config.php */
define('DISABLE_WP_CRON', false);

If you keep it disabled, add a server cron like:

*/5 * * * * php /path/to/wp/wp-cron.php > /dev/null 2>&1

Fix #5: Reduce batch pressure & skip problematic sizes

  • Temporarily exclude giant image sizes in Smush settings, then re-run bulk. Re-enable sizes after the main queue clears.
  • Bulk smaller chunks: run bulk, stop when it slows, then continue. This mimics “smaller batches” on tight hosts.

Fix #6: Host-level knobs that help

  • DNS: Use a fast resolver (e.g., 1.1.1.1 / 8.8.8.8). Slow DNS → slow TLS handshakes → timeouts.
  • PHP/cURL: Make sure the curl extension is enabled and up to date.
  • Timeouts: If your host enforces a very low request or process timeout, ask support to raise it for outbound HTTP from PHP.

Diagnostics you can run

  1. Basic connectivity from the server (SSH):
curl -I https://wpmudev.com
curl -I https://wordpress.org
  1. Log timeouts:
/* wp-config.php */
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false); // keep errors out of HTML
// Re-run bulk, then check /wp-content/debug.log for HTTP/cURL 28 lines

When it’s still failing

  • Re-test with security/WAF plugins disabled. If it works, add Smush’s domains to that tool’s allowlist.
  • Open a ticket with your host: “Outbound HTTP(S) from PHP hits timeouts during Smush bulk image optimization (cURL 28). Please confirm firewall/WAF/DNS and raise request timeouts.”

FAQ

Is this a Smush bug? Usually not...cURL error 28 means the request didn’t complete before the timeout. It’s most often networking, DNS, or host limits.

Can I keep higher timeouts permanently? Yes, 30–60 seconds for heavy jobs is common on shared hosting. Use the filters above.

Why does single image work, but bulk fails? Bulk queues many requests. Slight latency plus strict timeouts can tip bulk into timeouts even when singles succeed.

Need human WordPress help?

WP Assistant is a free tool created by Atiba Software, a WordPress design and development company located in Nashville, TN. If you need more personalized WordPress assistance let us know, and we’ll get back to you ASAP!