Troubleshooting Guide

Cron Job Not Running? Here's How to Fix It

Your cron job should be running, but it's not. Let's diagnose and fix it.

Quick Diagnostic Checklist

Is the cron daemon running? systemctl status cron
Is your crontab loaded? crontab -l
Check cron logs for errors grep CRON /var/log/syslog | tail -20
Does the script run manually? /path/to/your/script.sh

If your cron job isn't running, one of these six issues is almost certainly the cause. Let's go through each one.

1. The Cron Daemon Isn't Running

First, verify that the cron service is actually running:

# Check status
systemctl status cron

# If it's not running, start it
sudo systemctl start cron

# Enable it to start on boot
sudo systemctl enable cron

On some systems (like CentOS/RHEL), the service is called crond instead of cron.

2. PATH Issues — The #1 Cause

This is the most common reason cron jobs fail. Cron runs with a minimal PATH:

/usr/bin:/bin

If your script depends on binaries in /usr/local/bin, /opt/, or anywhere else, cron won't find them. A job that works perfectly when you run it manually will fail silently under cron.

The fix: Use absolute paths for everything.

# Bad - cron might not find node
* * * * * node /home/user/app/script.js

# Good - use absolute path
* * * * * /usr/bin/node /home/user/app/script.js

Find the full path to any command with which:

which node
# /usr/bin/node

which python3
# /usr/bin/python3

Alternatively, set PATH at the top of your crontab:

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

* * * * * node /home/user/app/script.js

3. Environment Variables Are Missing

Cron doesn't load your .bashrc, .bash_profile, or .profile. Any environment variables you set there won't exist when cron runs your job.

If your script relies on environment variables like DATABASE_URL or API_KEY, you have two options:

Option 1: Set them in the crontab:

DATABASE_URL=postgres://localhost/mydb
API_KEY=secret123

0 * * * * /home/user/scripts/backup.sh

Option 2: Source them in your script:

#!/bin/bash
source /home/user/.env
# rest of your script

4. Permission Problems

Your script needs to be executable:

chmod +x /path/to/script.sh

Also check that the user running the cron job has permission to:

  • Read the script file
  • Write to any output files or directories
  • Access any resources the script needs

If you're adding jobs to /etc/cron.d/, the file must be owned by root and have permissions 644:

sudo chown root:root /etc/cron.d/myjob
sudo chmod 644 /etc/cron.d/myjob

5. Shell Differences

Cron uses /bin/sh by default, which might be dash on Debian/Ubuntu — not bash. If your script uses bash-specific features (like [[ or arrays), it will fail.

The fix: Either add a shebang to your script:

#!/bin/bash
# Your bash-specific code here

Or set the shell in your crontab:

SHELL=/bin/bash

* * * * * /home/user/script.sh

6. The Cron Expression Is Wrong

Cron expressions are easy to get wrong. Common mistakes:

  • 0 0 * * * runs at midnight, not every hour
  • * * * * * runs every minute, not every hour
  • Day of month and day of week are OR'd together, not AND'd

Use our cron expression validator to check your expression and see the next run times.

How to Debug Any Cron Job

If you've checked all the above and the job still isn't running, follow this debugging process:

Step 1: Redirect output to a file to capture errors:

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

Step 2: Check the log after the job should have run:

cat /tmp/cron-debug.log

Step 3: Test your command exactly as cron runs it:

# Simulate cron's minimal environment
env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=$HOME /bin/sh -c '/path/to/script.sh'

If this fails but running the script directly works, you've found your environment issue.

The Job Runs But Fails Silently

Sometimes the job is running — it's just failing without telling anyone. This is the most dangerous scenario because you won't know until something breaks downstream.

Check your cron logs:

grep CRON /var/log/syslog | grep -i your-script-name

If you see entries, the job is running. But cron only logs that it started the job — not whether it succeeded or failed.


Prevent This From Happening Again

Here's the real problem: cron doesn't tell you when jobs fail. You just spent time debugging because you had no idea the job wasn't running. Next time, you might not notice for days or weeks.

The fix is external monitoring. Add a heartbeat ping to your cron job that only fires on success:

0 2 * * * /home/scripts/backup.sh && curl -fsS https://api.cronsignal.io/ping/your-check-id

If the job doesn't run — or runs but fails — the ping doesn't fire, and you get alerted immediately.

Never debug silent cron failures again

CronSignal alerts you the moment a job doesn't run. Know about failures before they become disasters.

Start Monitoring Free

3 checks free. No credit card required.

Need help with cron expressions? Use our cron validator to check syntax or cron generator to build expressions visually.