What are the steps to troubleshoot and resolve this issue as per title?
When I try to run manually, I get a page immediately, and the error message "Attempting to re-run cron while it is already running."
The cron semaphore is probably locked. You could try calling drupal_cron_cleanup() from anywhere in your code (that doesn't happen to be invoked by cron) and that should unlock your cron semaphore variable.
If you have drush configured in Drupal 6 you could also try:
$ drush vdel -y cron_semaphore
cache_bootstrap
.
drupal_cron_cleanup()
seems not to be updated.
The error message you are seeing would happen if the following two conditions are met:
This error message is therefore a symptom of a cron tasks that is either failing or taking too long to run. (Note: I realise you have already found the culprit, but I wanted to add an answer for people who find this page via searches, as I did)
The first thing to understand is how Drupal cron tasks are run. The Drupal cron is invoked at regular intervals - either through a cron job on your server, or after every page load if you use the poor man's cron which is Drupal's default.
The cron tasks are not necessarily run every time cron is invoked however - there is a setting in Drupal (default is 3 hours) which says how often cron tasks should be run. But this delay of 3 hours only applies if the cron tasks have finished successfully.
In Drupal 7, cron uses Drupal's locking mechanisms, which provides a cooperative, advisory lock system. One of the features of this lock system is that locks expire after a certain time. In the case of cron, it expires after 4 minutes - so if your cron is invoked every 3 minutes and the previous cron job hadn't finished by that time (either it crashed or was very slow), you would indeed get this error message.
The fact you set the cron to be every 12 hours does not make a difference - because the Drupal cron task is failing/taking too long, Drupal assumes it hasn't been run so tries to run it again as soon as cron is invoked. The twelve hour delay only applies to successful cron runs.
The cron semaphore variable does not exist any more in Drupal 7 - this was for an older version of Drupal. In Drupal 7 there is no reliable way to manually release a lock, because the locking backend might change - however if you are using the core locking mechanism then you can release cron locks by editing the database:
DELETE FROM semaphore WHERE name = 'cron';
But by doing this you would only be fixing the symptoms - the problem that needs addressing is why is cron failing / taking so long to run.
The cron_semaphore
variable did exist in Drupal 6, but you're using Drupal 7, so the semaphore locks moved into separate table called semaphore
.
So solution to unlock the cron semaphore would be:
Drupal 7
drush sqlq "TRUNCATE semaphore"
Drupal 6
drush -y vdel cron_semaphore
drush sql-query "DELETE FROM semaphore WHERE name='cron'"
You can debug the cron by using Cron Debug module.
Cron Debug will help you find cron processes which
- fail due to programming or runtime errors
- time out (PHP, server, database)
- are very slow
Cron Debug will also allow you to test run specific cron functions while not running others. This can be nice for developing cron functions where you don't want to run a full cron.php with all maintenance, alerts and other tasks every time you test your own function.
This is how I solved the cron issue:
name = cron
On Drupal 7, as even another option,
Via drush cron
I was getting,
WD cron: Attempting to re-run cron while it is already running. [warning]
Cron run failed. [error]
This was on development environment and happened because a previous cron was running and got interrupted.
On includes/common.inc
, at line 5413, or around, you'll find this block, https://cgit.drupalcode.org/drupal/tree/includes/common.inc?h=7.x#n5413
// Try to acquire cron lock.
if (!lock_acquire('cron', 240.0)) {
// Cron is still running normally.
watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING);
}
Modify the if
with an && FALSE
,
// Try to acquire cron lock.
if (!lock_acquire('cron', 240.0) && FALSE) {
// Cron is still running normally.
watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING);
}
And rerun cron. That will allow it to run.
Please don't deploy this and revert it back after it finishes. It also helps with debugging.
You could try the following:
1. Release the cron lock
In Drupal 8+, the cron lock is in the "semaphore" table with the key name "cron". This can be removed using this Drush command:
drush sqlq "DELETE FROM semaphore WHERE name = 'cron';"
Or if you don't have Drush, and you can execute PHP in the Drupal site (e.g. using the Devel PHP module), you can run one of the following:
\Drupal::database()->query("DELETE FROM semaphore WHERE name = 'cron';");
\Drupal::lock()->release('cron');
2. Find the offending error in the error log
The error log is at "Reports > Recent log messages" (/content/admin/reports/dblog).
If the error log is filled with message saying "Attempting to re-run cron while it is already running.", then you might need to disabled the automatic cron temporarily while you find the issue:
3. Disable cron
Go to the cron settings (/content/admin/config/system/cron) and change "Run cron every" to "never".
4. Find and uninstall the offending module/s
There's a good chance that the issue is caused by some process that a module is trying to run in a cron hook. The module might not be problematic in itself; it might be an incorrect setting that's causing the process to fail.
5. Re-enable cron
On most sites, cron should be set to run every 1 or 3 hours. By default, it will run in "poor man's cron" module, meaning it will run only when people visit the site. However it can be run more regularly by triggering it with a "cron job" on the server (requires advanced setup).
A quick universal solution for Drupal 7, 8, 9, 10, 11 to unlock cron, stuck in the "already running" status is to use this Drush command:
drush sql:query "DELETE FROM semaphore WHERE name='cron'"
I've come up against this a few times. In Drupal 6 If you don't use drush you can fix it like this:
1 Remove the cron_% variables from the variables table.
SELECT * FROM variable WHERE name like "cron%";
DELETE FROM variable WHERE name like "cron%";
2 clear Drupal cache at: /admin/settings/performance
by pressing the 'clear cached data' button at the bottom of the page.
3 run cron from admin panel /admin/reports/status/run-cron don't run it from comand line as this can cause problems.
4 Check that the next automatic cron run completes as normal.
You can debug by using xdebug , run cron from admin interface Admin > Configuration > system > cron.
drush sqlq "DELETE FROM semaphore WHERE name = 'cron';"