TechCompare LogoTechCompare

How to debug cron jobs: logging, email output, and troubleshooting silent failures

Never deploy a cron job without output capture. At minimum, redirect to a log file. For production, add structured logging with timestamps, exit codes, and runtime. And always use absolute paths or set PATH in the crontab.

Cron's default failure mode is silence. If a job fails, cron sends the output to the user's local mail spool, which on most modern systems goes unread because nothing is configured to deliver it. The result: your job has been failing for weeks and you had no idea. Fixing this means redirecting output somewhere you'll actually see it.

By TechCompare · Updated

Schedule pattern
Cron logging and debugging
logging-debugging
Category
Pitfalls
Common cron mistakes and fixes

How this is calculated

Three debugging strategies work. First, redirect STDOUT and STDERR to a log file: 0 * * * * /path/to/script >> /var/log/myjob.log 2>&1. Second, set [email protected] at the top of your crontab to get email on every execution. Third, wrap the command in a script that logs the start time, exit code, and runtime duration. The most common silent failure cause is missing environment: cron runs with a minimal PATH (typically /usr/bin:/bin) and no shell profile loaded. Always use absolute paths to executables in cron commands, or set PATH explicitly in the crontab.

Verdict

Silent failure is cron's default mode because output routes to the user's local mail spool, which usually goes unread on modern systems. Redirect both streams to a log file ('>> /var/log/job.log 2>&1'), set MAILTO at the top of the crontab for email alerts, and remember cron runs with PATH=/usr/bin:/bin and no shell profile loaded. Hard-code absolute paths or set PATH explicitly.

More Cron scenarios

Frequently asked questions

Why does my cron job fail silently with no error output?
Because cron sends a job's output to the user's local mail spool, and on most modern systems nothing delivers that mail anywhere you'll read it. The job has been erroring for weeks and you'd never know. The fix is to redirect output explicitly: append >> /var/log/myjob.log 2>&1 to the cron line so both STDOUT and STDERR land in a file.
Why does my script work in the shell but fail under cron?
Cron runs with a minimal environment: PATH is typically just /usr/bin:/bin, and your .bashrc and .profile never load. A command like node or aws that resolves fine in your login shell isn't on cron's PATH. Use absolute paths inside the script and cron line, or set PATH explicitly at the top of the crontab to match your interactive environment.
How do I get cron to email me when a job fails?
Set [email protected] at the top of the crontab, and cron mails any output the job produces. The catch is the server needs a working mail transfer agent for delivery, which most cloud VMs no longer have. For reliable alerting, pipe output to a log file and hook that into your logging stack, or use a wrapper that posts failures to Slack or PagerDuty directly.