I ran cron and aborted the execution. Now I get this message:

Attempting to re-run cron while it is already running.

In Drupal 7, I could delete the cron_semaphore variable.

What's the way to achieve the same in Drupal 8?


It's now in the semaphore table with the key name "cron". This can be removed via a drush sqlq "DELETE FROM semaphore WHERE name = 'cron';" command.

Or, if you can execute PHP in Drupal bootstrapped environment, you can run the line:

| improve this answer | |
  • 1
    drush php:eval '\Drupal::lock()->release("cron");' – Gogowitsch Jul 14 '18 at 18:17

For Drupal 8 run:

drush sqlq "DELETE FROM semaphore WHERE name = 'cron';"
| improve this answer | |

Thanks to Shawns answer..

drush php-eval "\Drupal::lock()->release('cron');"

Seemed to help!

| improve this answer | |
  • Does not work (D8.8.5). – Berend de Boer May 17 at 22:44
  • It didn't work for me either, but then I tried drush php-eval "\Drupal::lock()->acquire('cron', 10);" first a couple of times and finally could call drush php-eval "\Drupal::lock()->release('cron');" to release the stuck lock – David Thomas Jun 23 at 3:48

Drupal 7 doesn't anymore uses the cron_semaphore variable, but a lock. See drupal_cron_run(), and in particular the following lines, part of that function.

// Try to acquire cron lock.
if (!lock_acquire('cron', 240.0)) {
  // Omissis
// Release cron lock.

Porting those lines to Drupal 8 is quite straight, since Drupal 8 has a service for getting and releasing a lock.

The equivalent code is in Cron::run().

// Try to acquire cron lock.
if (!$this->lock->acquire('cron', 900.0)) {
  // Omissis
// Release cron lock.

If you need to unlock it in a host where you cannot use Drush, as it happens to me, to achieve the same from an external script that bootstraps Drupal would require code similar to the following one.

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Site\Settings;


$autoloader = require_once 'autoload.php';

function cron_unlock_access_allowed(Request $request) {
  $account = \Drupal::service('authentication')->authenticate($request);
  if ($account) {
  return \Drupal::currentUser()->hasPermission('administer site configuration');

try {
  $request = Request::createFromGlobals();
  $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
catch (HttpExceptionInterface $e) {
  $response = new Response('', $e->getStatusCode());

\Drupal::moduleHandler()->addModule('system', 'core/modules/system');
\Drupal::moduleHandler()->addModule('user', 'core/modules/user');

if (cron_unlock_access_allowed($request)) {
  $status_code = 200;
else {
  $status_code = 403;
$response = new Response('', $status_code);

I adapted the code of authorize.php. I changed the user permission required to run the script, which I placed in the directory containing the authorize.php file, in the cron_cleanup.php file.

If you can run Drush, it gets easier. (See @dman's answer.)

| improve this answer | |

Got to this page when my D7 installation stuck. I released it by using

php-eval "drupal_cron_cleanup()"

| improve this answer | |
  • The question is for Drupal 8, not Drupal 7. Furthermore, in Drupal 7 that function is marked deprecated. – kiamlaluno Dec 17 '17 at 17:05
  • In fact, Drupal 7 itself uses lock_release('cron') to release the cron lock. – kiamlaluno Dec 17 '17 at 17:07

If you can't get it to work in Drupal 8 with the suggested steps from above - perhaps you are using something like Redis and the cron lock is stored there. In this case you can progress with:

drush php-eval '\Drupal::service("lock")->release("all")'
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.