TL;DR: Three warnings that look alike come from three different layers, and only one of them is usually a real fault.
- "The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled." — a WP-CLI message describing your configuration. Fine if a real cron job replaces it, fatal if nothing does.
- "The ALTERNATE_WP_CRON constant is set to true. WP-Cron spawning is not asynchronous." — cron runs on a redirect instead of a background request.
- "Maximum simultaneous queues already in progress (1 queue)." — Action Scheduler, not WP-Cron. The concurrency limit is 1 by default.
- A missing WooCommerce daily event is a registration problem, not a running problem.
- The only test that matters: did a due event actually run in the last few minutes?
/ The message
What does "The DISABLE_WP_CRON constant is set to true" mean?
It means exactly what it says, and it is a description of your configuration rather than a diagnosis of a problem. The wording comes from WP-CLI: the wp cron test command tries to spawn WP-Cron over HTTP, and the first thing it does is refuse to try when the constant is set.
wp-cli/cron-command — Cron_Command::test()
if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) { WP_CLI::error( 'The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.' ); } if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { WP_CLI::warning( 'The ALTERNATE_WP_CRON constant is set to true. WP-Cron spawning is not asynchronous.' ); }
"Spawning" is the specific thing being reported. WordPress normally checks for due events on page loads and, when it finds one, fires a non-blocking request to wp-cron.php to run it. That self-triggering is what the constant disables. Nothing about scheduling changes: events are still registered, still stored, still due. They just have nobody to run them.
/ Is it a fault?
Is DISABLE_WP_CRON on its own a problem?
No — on a busy site it is the recommended setup. Leaving the default in place means every page load carries a scheduling check, and on a site with real traffic that is thousands of pointless checks an hour to run a job that needs to fire once. Setting the constant and handing the schedule to the operating system is the standard fix, and it makes cron timing predictable instead of traffic-dependent.
It becomes a fault the moment nothing replaces it. The constant is one half of a two-part change, and the second half lives outside WordPress:
crontab — the half that has to exist
# wp-config.php # define( 'DISABLE_WP_CRON', true ); # crontab -e — hit wp-cron.php once a minute * * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1 # or, better, skip HTTP entirely * * * * * cd /var/www/example && wp cron event run --due-now --quiet
So the question to answer is never "is the constant set" — it is "is anything hitting the scheduler". Our WP-Cron developer reference covers the scheduling API itself; what follows here is about reading the warnings.
/ Alternate cron
What does the ALTERNATE_WP_CRON warning mean?
That cron is running, but through a redirect rather than a background request. With ALTERNATE_WP_CRON enabled, WordPress appends a query string to a visitor's page load and redirects them, running the due events during that redirected request. It exists for hosts where the site cannot make loopback requests to itself — the mechanism WP-Cron normally relies on.
WP-CLI reports it as a warning rather than an error because it works, with caveats. Cron work now happens inside a real visitor's request, so a slow job is a slow page for whoever was unlucky enough to trigger it, and the redirect can interact badly with page caching. It is also still traffic-dependent: no visitors, no cron. Managed hosts sometimes turn this on as a platform feature, which is why it shows up on sites nobody deliberately configured — the WP Engine cron setup is the best-known example.
/ Action Scheduler
What does "Maximum simultaneous queues already in progress" mean?
This one is not WP-Cron at all. It is an Action Scheduler admin notice, and it appears on the Scheduled Actions screen when the number of open claims has reached the allowed concurrency. The full string is pluralised on the claim count, which is why people see it as "(1 queue)":
ActionScheduler_ListTable::display_admin_notices()
if ( $this->runner->has_maximum_concurrent_batches() ) { $claim_count = $this->store->get_claim_count(); // 'Maximum simultaneous queues already in progress (%s queue). // No additional queues will begin processing until the current queues are complete.' } // ActionScheduler_Abstract_QueueRunner public function has_maximum_concurrent_batches() { return $this->store->get_claim_count() >= $this->get_allowed_concurrent_batches(); } public function get_allowed_concurrent_batches() { return apply_filters( 'action_scheduler_queue_runner_concurrent_batches', 1 ); }
The default limit is 1. One batch running means the claim count is 1, which is already >= 1, which shows the notice. On a healthy site that is a normal thing to catch mid-pass and it clears by itself. It only signals trouble when the queue stops draining while the notice stays up, which means a claim is held by something that is never going to finish.
| Symptom | Likely cause | Where to look |
|---|---|---|
| Notice clears within a minute | A batch was simply running | Nothing to do |
| Notice permanent, pending count falling | Throughput limit, not a stall | action_scheduler_queue_runner_concurrent_batches |
| Notice permanent, pending count rising | Stale claim holding the only slot | In-progress actions older than the batch time limit |
| No actions ever move to complete | Nothing is triggering the runner | Whether cron runs at all |
/ Stuck claims
How do you clear a stuck queue?
Find the claim holder before changing any limits. A batch has a time limit — 30 seconds by default — so an action sitting in-progress for an hour is not slow, it is abandoned, usually because the PHP process running it was killed mid-execution and never got to release the claim.
- Sort by status. On Tools → Scheduled Actions, filter to In-progress and check the started time. Anything far past the batch time limit is a candidate.
- Deal with the action, not the queue. Cancel it, or re-run it once you know why it hung. A single action that consistently exceeds the time limit will keep recreating this state.
- Drain the backlog explicitly.
wp action-scheduler run --batches=0keeps processing until the queue is empty, which is far faster than waiting for minute-by-minute cron ticks. - Only then consider concurrency. Raising
action_scheduler_queue_runner_concurrent_batchesadds throughput on a site that is genuinely saturated — and multiplies the deadlock risk on the claims table if you push it hard.
That last point is a real trade-off, not a caution: concurrent runners compete for the same rows when claiming, which is the mechanism behind Action Scheduler deadlocks under load. Action Scheduler's own performance documentation treats the default of one batch as a deliberately conservative starting point.
/ Missing events
Why is a WooCommerce daily event missing from the schedule?
Because it was never re-registered. WooCommerce schedules a fixed set of recurring hooks on activation — woocommerce_scheduled_sales, woocommerce_cleanup_sessions, woocommerce_cleanup_personal_data, woocommerce_cleanup_logs, woocommerce_cancel_unpaid_orders, woocommerce_geoip_updater, woocommerce_tracker_send_event and woocommerce_cleanup_rate_limits — and clears every one of them on deactivation.
An interrupted update, a migration that copied the database but not the options in a consistent state, or a plugin that cleared schedules on its way out can leave one of those hooks unregistered. It is not a cron failure: cron is running fine, there is simply no event to run. Which is why the fix has nothing to do with cron configuration.
WP-CLI — check registration, then re-register
# Is the event actually scheduled? wp cron event list --fields=hook,next_run_relative,recurrence | grep woocommerce # Nothing listed? Re-run the activation routine. wp plugin deactivate woocommerce && wp plugin activate woocommerce # Confirm, then force one run to prove it works. wp cron event run woocommerce_cleanup_sessions
/ Verification
How do you prove cron is actually running?
By watching a due event stop being due. Every other check is indirect: the constant tells you about configuration, the notice tells you about concurrency, and neither tells you whether work is getting done.
Run wp cron event list and note the next run time of an event that is overdue. Wait past the point where your system cron should have fired, list again, and compare. If the timestamp moved, the pipeline works end to end — constants, triggers and all. If it did not move, you have isolated the problem to the trigger, and the warnings above become useful as clues rather than as verdicts. WordPress's Plugin Handbook chapter on cron documents the scheduling side of that loop.
A warning describes your configuration. Only a due event that stops being due proves anything actually runs. — the only cron test that matters
wp cron test — see the WP-CLI command reference.