Why your cron job isn't running
Updated 16 October 2026
When a cron job doesn’t run, it isn’t always clear where to look for the error. Go through these checks in order: first whether cron tried to run the job, then why the command failed.
1. Is the cron service running?
systemctl status cron # Debian, Ubuntu
systemctl status crond # RHEL, Fedora, Rocky, AlmaLinux
If it’s stopped, start it and enable it at boot:
sudo systemctl enable --now cron
A Docker container usually has no cron running unless its image starts it. Check that the process is there with ps aux | grep cron.
2. Did cron start the job?
Cron logs each command it starts. Look for your job around the time it should have run:
grep CRON /var/log/syslog # Debian, Ubuntu
sudo journalctl -u cron --since today # Debian, Ubuntu with systemd
sudo journalctl -u crond --since today # RHEL, Fedora
sudo tail -n 50 /var/log/cron # RHEL, CentOS
- The command is in the log: cron ran it, and the problem is in the command. Skip to step 4.
- It isn’t there: check the schedule and the crontab, in step 3. Also make sure you are reading the right log, since it depends on the distribution.
3. Is the schedule what you think?
-
Test the expression. Paste it in the cron tester and check its next runs. A common surprise: when both the day of the month and the day of the week are set, cron runs on either.
0 0 13 * 5runs on every 13th and every Friday. -
Check the server’s time zone. Cron uses the time zone of the server, which may not be yours:
timedatectl | grep "Time zone". Some implementations, like cronie, also acceptCRON_TZ=in the crontab. After changing the server’s time zone, restart cron. -
Check whose crontab it is.
crontab -lshows yours, andsudo crontab -lshows root’s. The lines in/etc/crontaband/etc/cron.d/have an extra field with the user, before the command:0 3 * * * root /usr/local/bin/backup.sh -
Name the files in
/etc/cron.d/without dots. On Debian and Ubuntu, cron ignores a file likebackup.cron: name itbackup. -
End the crontab with a newline. Cron may ignore a last line without one.
crontab -eusually adds it, but a file you copied may not have it.
4. Does the command work in cron’s environment?
Cron doesn’t read your shell profile, so the command runs in a more limited environment than your terminal’s. These are the most common differences:
-
PATHis short, often just/usr/bin:/bin. Commands in/usr/local/bin, or installed with nvm, rbenv or pyenv, aren’t found. Use absolute paths, like/usr/local/bin/node, or setPATHat the top of the crontab:PATH=/usr/local/bin:/usr/bin:/bin -
The shell is
/bin/sh, not bash, sosource,[[ ]]or arrays fail. Run the script with bash (/bin/bash /path/to/job.sh) or setSHELL=/bin/bashin the crontab. -
%means a new line in a crontab line, sodate +%Fbreaks the command. Escape it:date +\%F. -
The working directory is the home directory, so relative paths may point to the wrong directory. Use absolute paths, or
cd /path/to/app && .... -
The variables of
.bashrcor.profilearen’t there: API keys,DATABASE_URL,JAVA_HOME. Set them in the crontab or load them in the script.
To try the command almost as cron runs it:
env -i HOME="$HOME" PATH=/usr/bin:/bin /bin/sh -c 'cd ~ && /path/to/job.sh'
5. Can cron run the script?
-
It must be executable, with
chmod +x /path/to/job.shand a first line like#!/bin/bash. - The crontab’s user needs access to what the script uses: files, directories, sockets.
-
Line endings from Windows (
\r\n) make it fail with/bin/bash^M: bad interpreter. Fix them withsed -i 's/\r$//' /path/to/job.sh.
6. Read the error
Cron emails the output of each command to the crontab’s user, or to MAILTO. If the server isn’t set up to send email, you won’t get that output. Keep it in a file instead:
0 3 * * * /path/to/job.sh >> /var/log/job.log 2>&1
Wait for the next run, or change the schedule to run it in a couple of minutes, and look for the error message in that log.
Know sooner the next time
These checks help you find the cause once you have noticed the problem. To know sooner, set up alerts for when the job doesn’t start, takes too long or ends with an error.