WooCommerce says "Action Scheduler: past-due actions found; something may be wrong", the number keeps climbing, and nothing in any log explains it. If the site sits behind Cloudflare (or any web application firewall), the firewall is one of the most likely causes - and one of the hardest to see.
WP-Cron is not a timer. When someone loads a page, WordPress sends a second request from your server back to your own site, to /wp-cron.php, and that request is what runs Action Scheduler's queue.
That request comes from your own server's IP address, carries no browser, and goes straight to a PHP file. To a firewall it looks like a bot. Bot Fight Mode, "I'm Under Attack" mode and many rate-limiting rules block it. The visitor's page still loads normally, so the site looks healthy - but the queue never runs, and WordPress never receives the request, so there is nothing to log.
Open Tools → Site Health. If the loopback request fails, it is listed there as a failed loopback. When loopback fails, nothing you change inside WooCommerce will make the queue run.
If you can, also look at Cloudflare → Security → Events, filtered to the path /wp-cron.php. Blocked or challenged requests from your own server's IP confirm it.
Action Scheduler starts its queue through two addresses, not one: /wp-cron.php and /wp-admin/admin-ajax.php. Both have to get through.
(http.request.uri.path in {"/wp-cron.php" "/wp-admin/admin-ajax.php"})
Within a few minutes the past-due count should start to fall. If it does not, use Fix 2, which avoids the firewall entirely.
If you have shell or cron access at your host, run the queue with WP-CLI instead. There is no HTTP request, so there is nothing for a proxy, firewall or rate limit to judge. In wp-config.php:
define( 'DISABLE_WP_CRON', true );
Then add a server cron job that runs every five minutes:
cd /path/to/wordpress && wp cron event run --due-now
Only set DISABLE_WP_CRON once the server cron is in place; with neither, nothing runs at all.
StallRadar Past-Due Monitor is a free plugin on WordPress.org that shows which plugin's actions are stuck, checks whether the queue can run (WP-Cron settings, loopback, time limits), and says what to fix first - instead of just deleting rows.
Get it free from WordPress.orgNot affiliated with Cloudflare, WooCommerce or Automattic.
The blocked request is the one your server sends to itself. The visitor's page loads normally, so nothing looks broken, and WordPress never receives the request it would have logged.
No. Run is a debugging tool for one stuck job. Once the queue can run again, it works through the backlog by itself.
The skip covers only the two addresses WordPress uses to start its scheduled tasks, and only for the rules you choose. If you would rather not open anything, use a server cron job with WP-CLI instead, which needs no web request.