Tools > Site Health shows "Action Scheduler: 1,204 past-due actions found; something may be wrong." Action Scheduler is the job queue WooCommerce and many plugins use for order emails, subscription renewals, stock updates, webhooks and Analytics imports. Past-due means those jobs are waiting and nothing is running them. It is almost always one of two things: the background runner never starts, or the jobs start and fail. Two checks tell you which.
Open Tools > Scheduled Actions (on WooCommerce sites also under WooCommerce > Status > Scheduled Actions) and click Past-due. Note the oldest scheduled date. Wait five minutes, browse a couple of pages on the front of the site, then reload. If the count has not dropped and nothing moved to In-progress or Complete, the runner is not starting. The runner rides on WP-Cron, which only fires when someone visits the site and the site can call itself. Look in wp-config.php for define('DISABLE_WP_CRON', true);: if it is there, a real server cron job must replace it, and often it was never set up or stopped after a host move. Also check Site Health > Status for "could not complete a loopback request": a security plugin, password protection on the whole site, or a firewall rule blocking the site's own address stops every background job.
Still on Scheduled Actions, click Failed, and open the Log column of a few rows. Each failed job names its hook (for example woocommerce_run_product_attribute_lookup_update_callback or a subscription renewal) and the error it hit. A PHP fatal error, a timeout, or "action failed via async request" repeated on the same hook means one plugin's job is broken and keeps the queue busy. Hooks that belong to a plugin you have since deleted show "no callbacks are registered"; those can never run.
| What you see | Cause | Fix |
|---|---|---|
Nothing moves; DISABLE_WP_CRON is true | WP-Cron is switched off and no server cron replaces it | Add a server cron job in your hosting panel that requests https://yoursite.com/wp-cron.php?doing_wp_cron every 5 minutes, or runs wp cron event run --due-now |
| Nothing moves; Site Health shows a loopback error | The site cannot call itself: security plugin, site-wide password, Cloudflare rule, or wrong DNS on the server | Allow requests from the server's own IP and to wp-cron.php and admin-ajax.php; see the loopback guide linked below |
| Queue only moves when you are logged in | A quiet site with page caching: visitors get cached pages, so WP-Cron is rarely triggered | Set up a real server cron as above; it runs whether or not anyone visits |
| Thousands of failed rows on one hook | One plugin's job throws an error every time | Read the log message, update or fix that plugin, then rerun a few rows by hand with Run to confirm |
| "no callbacks are registered" on old hooks | Jobs left behind by a removed plugin | Search the hook name, select those pending rows and use Cancel; they will never run |
| Screen is very slow, table has millions of rows | Completed and cancelled actions are not being cleaned up because the runner stalls | Fix the runner first; Action Scheduler then deletes finished actions older than 30 days on its own |
| Count drops, then jumps back daily | Runner works but is too slow for a busy shop | Run the queue from server cron with wp action-scheduler run every few minutes instead of relying on page visits |
After the fix, open Past-due again and reload every few minutes. The count should fall steadily and new rows should appear under Complete with recent dates. Place a test order or trigger the plugin's own job, and confirm its action completes within a few minutes. Then check Site Health again: the past-due warning clears once the backlog is worked through.
actionscheduler_actions table by hand. Pending renewals, order emails and webhooks in it are lost, and some shops then miss subscription payments.If you would rather someone else finds why the queue is stuck and fixes it, that is what the box below is for. Related: REST API and loopback errors, scheduled posts not publishing, WooCommerce order emails not sending.