Testing & Debugging
A cron expression is dense enough that it's easy to be confident about what it means and still be wrong. The good news: you should never have to guess. There's a reliable way to check your understanding before you deploy, and a short checklist for when a job mysteriously doesn't run.
💡 The Bottom Line
Never trust your own read of a cron expression for anything important — verify it with a tool that shows you the actual next several run times in plain English before you deploy it. And when a scheduled job silently doesn't run, the fix is almost always in the daemon's logs, file permissions, or the job's stripped-down environment — not in the cron expression itself.
Verify before you deploy
Before trusting any cron expression you've written — especially one combining several special characters — paste it into an online cron parser/tool. A good one will do two things:
- Translate the expression into a plain-English description ("At 09:00, only on Monday").
- List the next several actual run times, in real calendar dates, so you can eyeball whether they match what you expected.
This second part matters more than it sounds — seeing "next run: Monday, July 20 at 9:00 AM" catches mistakes that reading the raw expression alone would miss.
🔧 Try It Yourself
Take the expression from the end of Lesson 4 — */10 9-17 * * 1-5 — and run it
through a cron parser tool. Confirm the next few listed run times are all on weekdays, land on
a 10-minute boundary, and stay within the 9am-5pm window. If any of that looks off, that's
exactly the kind of mistake this step is meant to catch before it reaches production.
When a job silently didn't run
Cron jobs fail quietly — there's often no error dialog, no alert, just... nothing happened. When that's the symptom, work through this order:
📋 The debugging checklist
- Check the cron daemon's own logs (often
/var/log/cronor viasyslog, depending on the system) — this tells you whether cron even attempted to run the job at all, which immediately narrows down whether the problem is the schedule or the command itself. - Verify the script has execute permissions — a script that works fine
when you run it manually can still fail under cron if it isn't marked executable
(
chmod +x), or if cron is invoking it in a way that bypasses your usual permissions setup. - Check the
PATHenvironment variable — this is the single most common cause of "it works when I run it myself but not under cron." Cron jobs run in a minimal environment, often with a bare-bonesPATHthat doesn't include the directories your interactive shell has. A command that "just works" when you type it can fail under cron because cron simply can't find it.
⚠️ Gotcha: your shell's environment isn't cron's environment
Your interactive shell loads a profile (.bashrc, .zshrc, etc.)
that sets up a rich PATH, aliases, and environment variables. Cron jobs typically
run in a much sparser environment that skips most of that setup. The safest fix is to use
absolute paths for every command and file inside a cron job's script (/usr/bin/python3
instead of just python3), rather than relying on anything being on the
PATH at all.
🙋 There Are No Dumb Questions
Q: If the cron daemon's logs show the job actually ran, but it still didn't do what
I expected, what then?
A: At that point it's no longer a scheduling problem — the schedule worked, cron did its job.
Redirect the command's own output (both stdout and stderr) to a log file from inside the
crontab entry itself, so you can see exactly what the command printed or errored on when it
ran. That turns a mystery into an ordinary debugging problem in your actual script.
✅ Quick Check
A script works perfectly when you run it manually, but silently fails under cron. What's the most likely cause?
Next up: the common gotchas — timezones, day-of-month vs. day-of-week ambiguity, and other quirks worth knowing before they surprise you in production.