Lesson 6 of 6

Common Gotchas

Cron's syntax is small, which means most mistakes with it are the same handful of quirks, over and over, across every developer who's used it. Here's the field guide, so you recognize them the first time instead of the third.

💡 The Bottom Line

Almost every "why didn't this run when I expected" surprise with cron traces back to one of four things: which timezone the schedule actually runs in, the surprising OR-logic between day-of-month and day-of-week, whether Sunday is 0 or 7, or assuming a shorthand alias like @daily works everywhere it doesn't.

Gotcha 1: which timezone is this actually running in?

A cron expression itself has no timezone built into it — it's just five numbers. Whether 0 9 * * * means 9am server time, 9am UTC, or 9am in whatever timezone the scheduling system is configured for depends entirely on the system running it. This is one of the single most common sources of "why did this run 5 hours off from when I expected" bugs, especially when a server's system timezone differs from what the person writing the expression assumed.

⚠️ Gotcha: always confirm the timezone explicitly

Before trusting a schedule in production, check (don't assume) what timezone the specific system uses — Unix cron typically uses the host machine's local system timezone, while many cloud schedulers default to UTC or let you set a timezone explicitly per schedule. When in doubt, look for an explicit timezone setting rather than trusting a guess.

Gotcha 2: day-of-month AND day-of-week is actually OR

This one catches even experienced developers. Intuitively, you'd expect setting both the day-of-month and day-of-week fields to narrow a schedule down — "run only when both match." Most cron implementations do the opposite: if both fields are restricted (not *), the job runs when either one matches.

0 0 1 * 1

You might read this as "midnight, on the 1st of the month, if it's also a Monday" — a rare combination. It actually means: midnight on the 1st of the month, or midnight on any Monday — whichever comes first, every week. That's a dramatically more frequent schedule than most people expect from reading the expression.

⚠️ Watch Out

If you actually need "the 1st of the month and only if it's a Monday," most standard cron implementations can't express that directly in five fields — you'd need application logic inside the job itself to check the extra condition and exit early if it doesn't match. Don't assume setting both fields gives you an AND; verify with a parser tool (Lesson 5) whenever you set both fields to something other than *.

Gotcha 3: is Sunday 0 or 7?

The day-of-week field is documented as 0-6 with 0 meaning Sunday — but many implementations also accept 7 as an alternate value for Sunday, for compatibility with other conventions. Both often work, but which values are accepted (and whether 7 is silently treated as Sunday or rejected) varies by implementation. Don't assume — check the specific system's documentation if a schedule involves Sunday.

Gotcha 4: shorthand aliases aren't universal

@daily    (roughly equivalent to  0 0 * * *)
@hourly   (roughly equivalent to  0 * * * *)

Some cron implementations — including standard Unix cron — support convenient shorthand aliases like @daily, @hourly, @weekly, and @reboot. These are a nice readability win where they're supported. But they are not universal — many cloud schedulers and other systems that adopted cron syntax require the plain 5-field form only and will reject a shorthand alias outright. Don't assume a shorthand you learned on one system will work on another; check first.

🙋 There Are No Dumb Questions

Q: Given all these quirks, is cron syntax actually reliable to use at all?
A: Yes — these are edge cases and easy-to-verify details, not reasons to avoid cron syntax. The core five-field pattern (Lessons 2-4) is consistent everywhere it's used. The gotchas in this lesson are exactly the kind of thing a quick check with a parser tool (Lesson 5) catches before they ever reach production — that's the whole reason "verify, don't assume" has been a theme throughout this track.

🔧 Try It Yourself

Take the expression 0 12 15 * 5 and, before checking a tool, write out in plain English what you think it means — remembering the day-of-month/day-of-week OR quirk from Gotcha 2. Then verify with a parser tool. (Hint: it fires at noon on the 15th of the month, or at noon on any Friday — not only when both line up.)

✅ Quick Check

If both the day-of-month and day-of-week fields are set to specific (non-*) values, when does the job run in most standard cron implementations?


That's the whole track — time for the recap.

← Back to
Next →