Cron job not running? A checklist (and how to find out next time)
A cron job that doesn't run produces nothing: no error, no log line, no email. These are the causes we see most, roughly in order of how often they bite.
1. The environment is not your shell's
Cron runs with a minimal PATH (often just /usr/bin:/bin) and no profile. A command that
works in your terminal fails under cron because node, python3 from a virtualenv or
/usr/local/bin tools aren't found. Use absolute paths, or set PATH=... at the top of the crontab.
2. An unescaped %
In a crontab line, % means "newline, and send the rest to stdin". date +%F silently breaks
the command. Write date +\%F, or move the command into a script.
3. The wrong crontab or user
crontab -e edits the current user's table; /etc/crontab and /etc/cron.d/*
have an extra user column. A line copied between them without adjusting the format is ignored. Files in
/etc/cron.d with a dot in the name are skipped on Debian and Ubuntu.
4. Timezone and DST
Cron uses the system timezone (or CRON_TZ). A job at 02:30 doesn't run on the night clocks spring
forward, and runs twice when they fall back, in timezones with DST.
5. No newline at the end of the file
Some cron implementations ignore the last line of a crontab that doesn't end with a newline.
6. It runs, but fails
Cron mails output to the local user, which nobody reads. Redirect output to a log
(>> /var/log/job.log 2>&1) and check grep CRON /var/log/syslog or
journalctl -u cron to see whether cron started it at all.
Find out next time, automatically
Every item above has the same symptom: silence. A heartbeat monitor turns silence into an alert. Add a ping to the end of the job, and send the exit code so failures alert right away:
0 3 * * * /usr/local/bin/backup.sh; curl -fsS -m 10 https://cronpup.com/p/YOUR-UUID/$?
If the ping doesn't arrive on schedule (plus a grace period you choose), you get an email, a push or a Slack message. Set one up free (10 monitors, no card).