You added a cron job. You’re sure the syntax is right. But nothing happens. No output, no errors, just silence. Here’s how to figure out what’s wrong.

Check If Cron Is Actually Running

First, verify the cron daemon is alive:

1
2
3
4
5
6
7
# systemd systems
systemctl status cron
# or
systemctl status crond

# older systems
service cron status

If it’s not running, start it:

1
2
sudo systemctl start cron
sudo systemctl enable cron

Verify Your Crontab Is Loaded

Check that your cron job actually exists:

1
crontab -l

If you edited /etc/crontab or files in /etc/cron.d/, those have a different format (they include a username field):

1
2
3
4
5
# /etc/crontab format (note the 'root' user field)
* * * * * root /path/to/script.sh

# User crontab format (no user field)
* * * * * /path/to/script.sh

Mixing these formats is a common cause of silent failures.

The PATH Problem

This is the #1 reason cron jobs fail. Your interactive shell has a rich PATH with /usr/local/bin, ~/.local/bin, etc. Cron’s PATH is minimal:

1
PATH=/usr/bin:/bin

Your script works when you run it manually but fails in cron because it can’t find node, python3, docker, or whatever command you’re using.

Fix 1: Use absolute paths

1
2
3
4
5
# Bad
* * * * * python3 /home/user/script.py

# Good
* * * * * /usr/bin/python3 /home/user/script.py

Find the absolute path with which:

1
2
which python3
# /usr/bin/python3

Fix 2: Set PATH in crontab

1
2
PATH=/usr/local/bin:/usr/bin:/bin:/home/user/.local/bin
* * * * * python3 /home/user/script.py

Environment Variables Are Missing

Cron runs with almost no environment. Variables you set in .bashrc, .profile, or .env don’t exist.

Fix: Source your environment or set variables explicitly

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Source .bashrc (note: might not work if .bashrc has interactive checks)
* * * * * . /home/user/.bashrc && /home/user/script.sh

# Or set variables directly
* * * * * export API_KEY=xxx && /home/user/script.sh

# Or put them at the top of your crontab
API_KEY=xxx
DATABASE_URL=postgres://...
* * * * * /home/user/script.sh

Check the Cron Logs

Cron logs where it runs jobs. Find out what’s happening:

1
2
3
4
5
6
7
8
# Most Linux distros
grep CRON /var/log/syslog

# CentOS/RHEL
grep CRON /var/log/cron

# journalctl on systemd systems
journalctl -u cron --since "1 hour ago"

You’ll see entries like:

CRON[12345]:(user)CMD/home/user/script.sh)

If you don’t see your job listed at all, the crontab isn’t being read or the schedule hasn’t triggered yet.

Capture Output to Debug

By default, cron emails output to the local user. If you don’t have local mail configured, it vanishes. Redirect to a file:

1
* * * * * /home/user/script.sh >> /home/user/cron.log 2>&1

The 2>&1 captures both stdout and stderr. Now check cron.log to see what’s actually happening.

Permission Problems

Your script must be executable:

1
chmod +x /home/user/script.sh

If your script writes to files, cron runs as your user but might have different permissions context. Test by running:

1
sudo -u yourusername /home/user/script.sh

The Timing Gotcha

Cron uses the system timezone, not necessarily yours:

1
timedatectl

If your server is UTC and you’re in EST, a job scheduled for 0 9 * * * runs at 9 AM UTC (4 AM EST in winter, 5 AM EST in summer).

Also, */5 means “every 5 minutes” but starts from minute 0 — so it runs at :00, :05, :10, etc., not 5 minutes from when you saved the crontab.

The Script Works Manually But Not in Cron

If you’ve checked everything above and your script still only works interactively, create a wrapper that mimics cron’s environment:

1
2
3
4
5
6
#!/bin/bash
# test-cron.sh - simulate cron's environment
env -i \
    PATH=/usr/bin:/bin \
    HOME=$HOME \
    /home/user/script.sh

Run this wrapper. If it fails the same way cron fails, you’ve reproduced the issue and can debug from there.

Quick Debugging Checklist

  1. Is cron running? (systemctl status cron)
  2. Is the job in crontab? (crontab -l)
  3. Is the schedule correct? (Use crontab.guru to verify)
  4. Are you using absolute paths for commands?
  5. Are environment variables set?
  6. Is the script executable?
  7. What do the logs say? (grep CRON /var/log/syslog)
  8. What does redirected output show?

Nine times out of ten, it’s the PATH. Start there.