WP-CLI » Loopback Request Failed: Fix WP-Cron Status Code 0 in WordPress

Loopback Request Failed: Fix WP-Cron Status Code 0 in WordPress

Scheduled posts stay unpublished, backups never start and WooCommerce actions pile up. Tools > Site Health says Your site could not complete a loopback request, or a cron log shows something like HTTP GET request to https://example.com/... returned status code 0.

Status code 0 is not an HTTP error. It means the request never got an answer at all: your server tried to open a connection to its own domain and failed. That makes it a server or network problem, so the fix is on the server too.

WP-Cron is not a real cron. On a normal page load, spawn_cron() in wp-includes/cron.php sends a POST request to wp-cron.php on your own site, and that second request runs the due events.

That request is fired with 'timeout' => 0.01 and 'blocking' => false. WordPress does not wait for an answer, so when the connection fails nothing gets logged and the events simply stay due.

The Site Health test sends the same kind of POST to wp-cron.php but waits up to 10 seconds. That is why it is the place where you finally see the error: The loopback request to your site failed, this means features relying on them are not currently working as expected.


WP-CLI has a command that tests exactly this spawn request (docs):

wp cron test

A working site prints Success: WP-Cron spawning is working as expected. Anything else confirms the loopback problem. Next, check how far behind the queue is:

wp cron event list --fields=hook,next_run_relative,recurrence

Events whose next_run_relative is in the past are overdue. A long list of them means cron has not run for a while.

Run this on the web server itself, not on your laptop. Replace example.com with your domain:

getent hosts example.com
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://example.com/wp-cron.php

The first line shows the IP the server resolves for your domain. The curl line prints the HTTP status: 200 means the server can reach itself, 000 is the shell version of status code 0, and 403 means something is blocking the request.

The usual causes, depending on what you got:

  • After a migration, the server still resolves the domain to the old host, or to an IP that does not answer from inside the network.
  • The server can not reach its own public IP. Some NAT and cloud setups drop connections from a machine to its own public address.
  • A firewall, Cloudflare rule or bot protection treats your server’s own IP as a bot and drops or challenges it.
  • A 403 from a security plugin, a WAF rule or the password prompt on a protected staging site.

For a DNS or NAT problem, point the domain at the local web server in /etc/hosts on the server. Back up the file first, then add:

127.0.0.1   example.com www.example.com

This only works when the web server on that machine serves your site on 127.0.0.1. Behind a load balancer or a separate proxy, use the internal IP of the web server instead. Loopback requests skip SSL verification by default (the https_local_ssl_verify filter returns false), so a certificate that does not match 127.0.0.1 is not a problem.

See also  Action Scheduler Past-Due Actions Notice: Fix It With WP-CLI

For firewall and CDN blocks, allow the server’s own IP in the firewall, the security plugin and your Cloudflare WAF rules. For a password-protected staging site, exclude wp-cron.php from the password prompt or go straight to the server cron in Step 4.

Run wp cron test and the Site Health check again. When both pass, the overdue events run on the next page view.


Even with a working loopback, I prefer a real system cron on any site that matters. It runs on schedule without traffic and does not depend on the site reaching itself.

First stop WordPress from spawning cron on page loads. Back up wp-config.php, then add this above the /* That's all, stop editing! */ line, as described in the WordPress developer handbook:

define( 'DISABLE_WP_CRON', true );
loopback request failed wp cron status 0 wp config 1 - Loopback Request Failed: Fix WP-Cron Status Code 0 in WordPress
Where it goes in wp-config.php: above the “That’s all, stop editing!” line

Then add a crontab entry (crontab -e) for the user that owns the WordPress files. WP-CLI runs the events directly in PHP, with no HTTP request at all:

*/5 * * * * cd /var/www/example.com && wp cron event run --due-now --quiet >/dev/null 2>&1

Use the full path to wp if cron can not find it (which wp shows it). Without WP-CLI, the handbook’s wget --delete-after call to wp-cron.php also works, but that is a loopback request again and fails for the same reasons.

💡 Never set DISABLE_WP_CRON and forget the crontab. Then nothing runs at all, which is exactly what causes a lot of missed schedule errors.

In cPanel you add the job under Cron Jobs. In OpenPanel cron does not run in the host crontab: each user has a cron container, and jobs are defined in /home/USERNAME/crons.ini. The container value has to match the real container name (for example openlitespeed), and the command should use the container’s own php instead of a host PHP path. Their guide also suggests running the command manually inside the container first, so you know a failing job is the command and not cron.

A real cron also keeps background queues that ride on WP-Cron moving, like Action Scheduler. If WooCommerce still shows overdue actions afterwards, clear them with the commands in Action Scheduler Past-Due Actions Notice.

I would skip ALTERNATE_WP_CRON as a workaround here. It runs cron through a redirect instead of a loopback, but it adds ?doing_wp_cron to your URLs and makes visitors wait for it.

Keep fixing the loopback itself even after you switch to a server cron. Site Health also uses loopback requests to check code stability when you edit plugin and theme files in wp-admin, and some plugins rely on them for background processing.


TL;DR: “Status code 0” and a failed loopback in Site Health mean your server can not open a connection to its own domain, so WP-Cron never runs. Test it with wp cron test and curl on the server, fix the DNS, NAT or firewall cause, then switch to DISABLE_WP_CRON plus a system cron running wp cron event run --due-now. If scheduled posts were the symptom, the Missed Schedule error post covers the other causes.

Was this post helpful?

Leave a Comment

I enjoy constructive responses and professional comments to my posts, and invite anyone to comment or link to my site.

Recommended