Blog
Wild & Free Tools

Cron Job Running at Wrong Time — 5 Causes and How to Fix Them

Last updated: April 2026 7 min read

Table of Contents

  1. Cause 1: Timezone Mismatch (Server vs Your Time)
  2. Cause 2: Daylight Saving Time Shift
  3. Cause 3: Day-of-Week Numbering Differences
  4. Cause 4: OR Logic for Day Fields
  5. Cause 5: Server Clock Drift or NTP Failure
  6. Frequently Asked Questions

A cron job running at the wrong time is almost always a timezone issue — the server runs in UTC and your expression was written in local time. But there are four other causes that catch developers off guard, especially after clock changes.

Paste your expression into the crontab visualizer to see exactly when it will run in your timezone before you even touch the server.

Cause 1: Server Timezone vs Your Local Time

This causes ~80% of "cron runs at wrong time" reports. Cron uses the system's timezone — your cloud server is almost certainly UTC, but you wrote the expression expecting your local time (EST, PST, etc.).

Check your server timezone:

date
# Shows current date/time in server's timezone

timedatectl
# Shows system timezone and NTP sync status

Fix — Option A (convert expression to UTC): If your server is UTC and you want a job at 9 AM EST (UTC-5 in winter, UTC-4 in summer), use hour 14 in winter and 13 in summer. This means manually updating the expression when DST changes.

Fix — Option B (set CRON_TZ in crontab): Add a timezone variable at the top of your crontab:

CRON_TZ=America/New_York
0 9 * * * /path/to/script.sh

CRON_TZ is supported on Linux (Vixie cron, cronie). It tells cron to interpret the expression in your specified timezone and handle DST automatically.

Cause 2: Daylight Saving Time Causes a Skip or Double-Run

When clocks "spring forward," one hour is skipped. A cron job scheduled for 2:30 AM won't run the night clocks change — 2:30 AM doesn't exist that day. When clocks "fall back," one hour repeats. A 1:30 AM job may run twice.

DST behavior by timezone setting:

ScenarioServer in UTCServer in local TZCRON_TZ set
Spring forwardUnaffectedJob may skip onceJob may skip once
Fall backUnaffectedJob may run twiceJob may run twice

Fix: Schedule time-sensitive jobs at hours that are never ambiguous — avoid the 1:00-3:00 AM window in DST-observing timezones. Or keep the server in UTC and handle timezone conversion in application code.

Use the visualizer around DST transition dates to see if your schedule has a gap or duplicate.

Sell Custom Apparel — We Handle Printing & Free Shipping

Cause 3: Day-of-Week Numbering Is Platform-Specific

Standard cron: 0=Sunday, 1=Monday, ..., 6=Saturday (7 also = Sunday). Quartz Java: 1=Sunday, 2=Monday, ..., 7=Saturday. AWS EventBridge: 1=Sunday, 2=Monday, ..., 7=Saturday.

If you copy an expression from a Quartz context to Linux crontab, day-of-week numbers will be off by one. A job intended for Monday (Quartz: 2) would run on Tuesday (Linux cron: 2=Tuesday).

Check: Paste the expression into the crontab visualizer (which uses standard 0-6/7 numbering). If the days shown don't match what you intended, adjust the day-of-week field for your target platform.

DayStandard cronQuartz / AWS
Sunday0 or 71
Monday12
Friday56
Saturday67

Cause 4: Day-of-Month AND Day-of-Week Use OR Logic

When both field 3 (day-of-month) and field 5 (day-of-week) are non-wildcard values, most cron implementations apply OR logic — the job runs if either condition is true.

Example: 0 9 1 * 1 — you might expect "9 AM on Mondays that fall on the 1st." What you actually get: "9 AM on the 1st of every month, PLUS 9 AM every Monday." This expression runs far more often than intended.

Fix: Use * for whichever field you don't want to restrict. For "every Monday at 9 AM," use 0 9 * * 1 (day-of-month is *). For "9 AM on the 1st," use 0 9 1 * * (day-of-week is *).

The crontab visualizer shows OR-logic clearly — the calendar view will show many more run dates than you expected if you've hit this trap.

Cause 5: Server Clock Drift (Rare but Real)

If your server's system clock drifts significantly, cron jobs will fire at the "wrong" wall-clock time relative to your expectation. This is rare on cloud VMs (AWS, GCP, DigitalOcean all sync NTP), but can happen on bare-metal servers or VMs that haven't been maintained.

Check clock sync status:

timedatectl status
# Look for "System clock synchronized: yes"
# and "NTP service: active"

ntpstat    # if ntputils installed
chronyc tracking  # if chrony is the NTP client

Fix: Ensure systemd-timesyncd, ntpd, or chronyd is running and syncing. On AWS EC2, the Amazon Time Sync Service (169.254.169.123) should be configured as the NTP source.

After fixing drift issues, verify your cron schedule is still correct using the visualizer with the corrected server timezone.

Try It Free — No Signup Required

Runs 100% in your browser. No account, no install, no limits.

Open Free Crontab Visualizer

Frequently Asked Questions

How do I make cron use my local timezone instead of UTC?

Add "CRON_TZ=America/New_York" (or your timezone) at the top of your crontab file before the affected job lines. This works on most Linux cron implementations (Vixie cron, cronie). Alternatively, change the system timezone with "timedatectl set-timezone America/New_York", but be aware this affects all system processes, not just cron.

My cron job ran twice — what happened?

The most common cause is a daylight saving time "fall back" transition. When clocks are set back one hour, a one-hour period repeats, so a cron job scheduled within that window may trigger twice. The fix is to schedule such jobs outside the 1:00-3:00 AM window, or run the server in UTC (where DST doesn't apply).

How can I test my cron expression before deploying?

Paste it into our free crontab visualizer at /developer-tools/crontab-visualizer/ — it shows the next 20 run times in your local timezone on a calendar. This catches timezone errors, OR-logic surprises, and impossible dates before the job goes live on the server.

Launch Your Own Clothing Brand — No Inventory, No Risk