Cron do Magento 2 não roda: status missed e pending no cron_schedule

Pedido aprovado que não vira fatura, e-mail de nova venda que nunca chega, indexador parado no admin. Antes de culpar o módulo de pagamento, abra a cron_schedule: se estiver tudo em missed, nenhum job do Magento está sendo executado e o resto da loja é só consequência.

SELECT status, COUNT(*) AS total
FROM cron_schedule
GROUP BY status;

SELECT job_code, status, scheduled_at, executed_at
FROM cron_schedule
ORDER BY schedule_id DESC
LIMIT 15;

Missed quer dizer que o agendamento foi criado e ninguém apareceu para executar dentro da janela de tolerância: 15 minutos no padrão, o campo “Missed if Not Run Within” em Lojas > Configuração > Avançado > Sistema > Cron. Ou seja, quem gera a fila está vivo, quem consome não.

O crontab do usuário certo

Aqui mora a maioria dos casos: o agendamento foi parar no root, ou no seu usuário de deploy, e não no dono dos arquivos. O -u do crontab só funciona com privilégio, daí o sudo na primeira linha:

sudo crontab -u www-data -l
sudo -u www-data php bin/magento cron:install
sudo -u www-data php bin/magento cron:run --group=default

Se já existe um bloco do Magento naquele crontab, o cron:install responde “Crontab has already been generated and saved” e não faz nada; use -f pra sobrescrever. A linha que ele grava roda de minuto em minuto e joga a saída em var/log/magento.cron.log. E não instale isso no root: os arquivos que nascem em var, generated e pub/static ficam com dono errado e o PHP-FPM perde acesso depois.

O grupo travado no lock

Crontab certo e mesmo assim tudo cai em missed? O próximo lugar é o var/log/cron.log:

grep 'Could not acquire lock' var/log/cron.log | tail -20

Essa linha é o Magento desistindo do grupo porque a rodada anterior ainda segura o lock, quase sempre um job pesado que passa dos 15 minutos e atropela a janela de todo mundo atrás dele. Linha parada em running desde ontem não é a culpada: nas 2.4.7 e 2.4.8 o próprio observer marca essas linhas como error com a mensagem “Time out” depois de 24 horas, então não precisa sair dando DELETE na tabela. Ache o job_code lento e o resto da fila anda sozinho.

Se travou nisso e precisa de ajuda, me chama aqui.

Dúvidas? Faça um comentário logo abaixo ou envie uma mensagem clicando aqui.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *