DebuggingLinuxAdvanced10 min read

How to Debug Cron Jobs That Aren't Running

Cron jobs fail silently by default — no error, no output, nothing. This guide walks through every common reason a cron job stops working, from the obvious (it's not enabled) to the subtle (PATH vs. your terminal PATH).

Quick Debugging Checklist

  • cron daemon is running (`systemctl status cron`)
  • crontab has no syntax errors — validated in /debugger
  • output is redirected to a log file (`>> /tmp/cron.log 2>&1`)
  • all paths in the command are absolute
  • the script file is executable (`chmod +x`)
  • required environment variables are set in the crontab
  • the server timezone matches your expected schedule
  • cron logs show the job being triggered
1

Check if cron is running

First verify the cron daemon itself is active.

systemctl status cron

# Debian/Ubuntu

systemctl status crond

# RHEL/CentOS/Fedora

ps aux | grep cron

# Any Linux — look for a cron process

Tip: If cron is not running, start it: `sudo systemctl start cron` (Debian) or `sudo systemctl start crond` (RHEL).
2

Verify cron is logging

Enable cron logs if they're disabled, then tail them live.

tail -f /var/log/syslog | grep CRON

# Debian/Ubuntu

tail -f /var/log/cron

# RHEL/CentOS

journalctl -u cron -f

# systemd systems

Tip: Cron logs every job it runs. If your job time passes and nothing appears in the log, the crontab entry may not be parsed correctly.
3

Check the crontab syntax

Open your crontab and verify the expression is valid.

crontab -e

# Edit your crontab

crontab -l

# List current entries

Tip: Paste your cron expression into our Debugger tool at /debugger to validate it and preview the next 10 run times.
4

Capture cron output

By default, cron discards stdout and stderr (or mails them). Redirect output to a log file to see what's happening.

* * * * * /path/to/script.sh >> /tmp/cron.log 2>&1

# Redirect stdout + stderr to a file

* * * * * /path/to/script.sh 2>/tmp/cron-errors.log

# Redirect only stderr

Tip: Always add `>> /path/to/logfile 2>&1` during debugging. Remove it once the job is stable.
5

Fix PATH issues — the #1 cause of failures

Cron runs with a minimal PATH: usually `/usr/bin:/bin`. Commands that work in your terminal (node, python3, npm, docker) may not be found by cron.

which node

# Find the full path to a binary

PATH=/usr/local/bin:/usr/bin:/bin

# Add this line at the top of your crontab

* * * * * /usr/local/bin/node /home/user/app/script.js

# Use absolute paths in the command

Tip: The safest fix is to use absolute paths everywhere — `/usr/local/bin/python3` not `python3`.
6

Check environment variables

Cron does not load your shell's environment. Variables set in `.bashrc`, `.profile`, or `.zshrc` are NOT available to cron jobs.

MYVAR=value
* * * * * /path/script.sh

# Define variables at the top of the crontab

* * * * * . /home/user/.bashrc && /path/script.sh

# Source your profile (careful with interactive-only items)

* * * * * env -i HOME=/home/user /path/script.sh

# Explicit clean environment

Tip: For complex env setups, create a wrapper shell script that exports variables before calling the actual program.
7

Verify file permissions

The script must be executable by the user running the cron job.

ls -la /path/to/script.sh

# Check file permissions

chmod +x /path/to/script.sh

# Make the script executable

ls -la /path/to/

# The directory must also be accessible by the cron user

Tip: If the cron job runs as root but the script is owned by another user with restrictive permissions, it may still fail.
8

Test the command directly as the cron user

Simulate the cron environment by running the command as the same user and with a minimal environment.

sudo -u cronuser env -i HOME=/home/cronuser /path/script.sh

# Run as the cron user, clean env

su -s /bin/sh cronuser -c '/path/script.sh'

# Alternative: switch user and run

Tip: If this fails, you've found the problem. Fix the script or environment so this command succeeds.
9

Check for timezone/timing mismatches

Cron uses the system clock in the system timezone. If you expect 9 AM local time but the server is UTC, your job fires at the wrong time.

date

# Shows current server time + timezone

timedatectl

# Shows timezone info on systemd systems

TZ=America/New_York
0 9 * * * /path/script.sh

# Set timezone per-crontab (supported on modern cron)

Tip: Cloud schedulers (GitHub Actions, AWS EventBridge, GCP Cloud Scheduler) always use UTC. Convert your local time to UTC when setting up schedules.

Common Error Patterns

/bin/sh: python: not found
Cause: PATH issue — cron can't find `python`
Fix: Use the full path: `/usr/bin/python3` or set `PATH=/usr/local/bin:/usr/bin:/bin` at the top of crontab.
Permission denied
Cause: Script is not executable, or cron user lacks directory access
Fix: Run `chmod +x /path/script.sh` and ensure the parent directories are readable.
No output, no log entry
Cause: The job isn't being triggered. Likely a syntax error in the crontab, or cron isn't running.
Fix: Validate the cron expression, check `systemctl status cron`, and add output redirection.
Job runs at wrong time
Cause: Timezone mismatch — server is UTC, schedule is in local time
Fix: Check `date` and convert schedule to UTC, or use `TZ=` at the top of your crontab.
Job runs, but script exits with error
Cause: Missing environment variable (DB_URL, API_KEY, etc.) that exists in your shell but not in cron
Fix: Export variables at the top of the crontab, or load them from a `.env` file in the script.

Validate your cron expression

Use our free Debugger to validate syntax, see plain-English descriptions, and preview the next 10 run times — all in the browser.