You've spent 40 minutes staring at a crontab line that looks perfect. The command works when you paste it into the terminal. But cron never fires it. Before you blame the scheduler, hear the sentence every sysadmin eventually says out loud:
Cron runs your command in a near-empty room. No .bashrc. No aliases. No node, python or docker on PATH. Just /usr/bin:/bin, HOME, and LOGNAME. Everything your terminal shell loaded for you, cron never loads.
So the command "works" in your shell and "fails" under cron — because it's not the same command at all.
The 9 real reasons your job silently never runs:
-
No absolute paths. Your script calls
nodeorpython3, but cron's PATH doesn't include them. Fix: absolute paths everywhere, orexport PATHat the top of the script. -
No shebang.
/bin/shruns the file with a shell it wasn't written for. Add#!/bin/bash. -
Not executable.
chmod +x yourscript.sh— cron skips files it can't execute. - Missing newline. Cron silently ignores the last line of a crontab without a trailing newline. The classic.
-
No output redirection. Without
>> /tmp/job.log 2>&1, errors go to a local mailbox that doesn't exist on most minimal images. The error vanishes. You can't debug invisible errors. -
Crond isn't running.
systemctl status cron, orps aux | grep cron. Sometimes the daemon is just dead. - Script mtime too fresh. Classic Vixie cron skips a run if the file's mtime is newer than its last execution time. Edit → run → skipped, on purpose.
-
Malformed expression. One extra space, a
%outside its escape context, and the line silently dies. Validate your expression before you trust it. - The output worked because you ran it as root / user X, but cron runs as the crontab owner. Different user, different environment, different permissions.
The fastest debug ritual:
crontab -l # is the entry actually there?
systemctl status cron
* * * * * /tmp/job.sh >> /tmp/job.log 2>&1 # make errors visible
cat /tmp/job.log
That last line is the highest-leverage habit in all of cron debugging: always redirect output to a log you can read. The number of "impossible" cron failures that turn into a one-line fix the moment you see the error is genuinely absurd.
I keep the full 9-point checklist with per-cause fixes at https://cron-generator-kappa.vercel.app/guides/cron-not-running — bookmark it for the next 40-minute mystery. And if your expression itself is the suspect, validate it in plain English first: https://cron-generator-kappa.vercel.app
Which of the nine bit you hardest? For me it was the missing newline — an hour of my life that a trailing \n could have saved.
Top comments (0)