Debugging Cronjobs Running at Incorrect Times: Timezone and System Clock Configuration Issues


2 views

When cronjobs consistently run at unexpected hours (particularly showing an 8-hour discrepancy in your case), we're typically dealing with one of these fundamental timing layers:

# Current time verification commands
date               # System clock
timedatectl        # Systemd time management
ls -l /etc/localtime  # Timezone symlink verification

The Linux time system operates through several layers:

  1. Hardware Clock (RTC)
  2. System Clock (kernel time)
  3. Timezone Configuration
  4. Cron Daemon's Environment

Your specific issue suggests either:

  • Undetected timezone misconfiguration
  • Cron running with a different environment than shell
  • Improper service restart after tzdata changes

1. Verify actual cron environment:

# Create a test cron job that outputs environment
* * * * * /usr/bin/env > /tmp/cronenv.log

2. Check systemd services (modern Ubuntu):

systemctl status cron
journalctl -u cron -b --no-pager | grep -i timezone

3. Compare shell vs cron environments:

# In shell
echo $TZ
cat /etc/timezone

# In cron test job
* * * * * echo $TZ >> /tmp/crontz.log

Option A: Force system-wide timezone

sudo unlink /etc/localtime
sudo ln -s /usr/share/zoneinfo/America/Chicago /etc/localtime
sudo dpkg-reconfigure -f noninteractive tzdata
sudo systemctl restart cron

Option B: Explicitly set TZ in crontab

TZ=America/Chicago
0 4 * * * /path/to/command

Cron often runs with a minimal environment. To debug:

# Enhanced test job
* * * * * printenv > /tmp/fullcronenv.log 2>&1
* * * * * ls -l /etc/localtime >> /tmp/cronsymlink.log 2>&1

If you need to ensure proper environment inheritance:

# At crontab top
SHELL=/bin/bash
BASH_ENV=/etc/profile

After making changes:

# Check active timezone
date
timedatectl

# Verify cron sees correct time
* * * * * date >> /tmp/crondate.log

Remember that some cron implementations (like Vixie cron) may cache timezone data. A full service restart is often needed:

sudo service cron restart

When cron jobs execute earlier or later than expected, it's often related to timezone settings. In your case, cron jobs set to run at 4 AM (UTC) are triggering 8 hours early, suggesting a timezone mismatch between the system and cron's configuration.

First, verify your system's current time settings:

date
timedatectl status

This should show your configured timezone (CST in your case) and current system time.

Cron typically uses the system timezone, but there are exceptions:

  • Some cron implementations (like Vixie cron) use the system timezone
  • Others may use UTC by default
  • Environment variables can override this behavior

Check if cron is using a different timezone than your system:

sudo grep -i 'TZ' /etc/crontab /etc/cron.*/*
grep -i 'TZ' /etc/environment

Option 1: Explicitly set timezone in crontab

TZ=America/Chicago
0 4 * * * command

Option 2: Modify system-wide cron configuration

sudo nano /etc/default/cron
# Add or modify:
CRON_TZ=America/Chicago

Option 3: Adjust your cron schedule

# If cron is using UTC and you want 4 AM CST (which is 10 AM UTC)
0 10 * * * command

After making changes, monitor the next execution:

sudo tail -f /var/log/syslog | grep CRON
  • Check for user-specific crontabs that might have different timezone settings
  • Verify daylight saving time handling if applicable
  • Consider using systemd timers for more precise time control

Create a timer unit file:

[Unit]
Description=Run daily job at 4 AM CST

[Timer]
OnCalendar=*-*-* 04:00:00
TimeZone=America/Chicago
Persistent=true

[Install]
WantedBy=timers.target