Server config6 min read· Updated

Cron job not running? Seven things to check

The command works when you type it, but nothing happens when cron runs it. Start by making the error visible, then check the schedule, environment, paths, permissions and time zone.

Check the scheduleSee in plain English when your expression runs, and the next five run times.
Open Cron Expression Builder
On this page

    1. Capture the output

    Cron throws away anything the job prints unless mail is set up on the server, so errors disappear. Add a redirect to the end of the line and run it again:

    crontab
    */5 * * * * /usr/bin/php /home/site/htdocs/cron.php >> /home/site/cron.log 2>&1

    2>&1 sends error messages to the same file. After the next run, the log usually tells you exactly what is wrong. Make sure the user running the job can write to the log file.

    2. Check the schedule means what you think

    Paste the five fields into the Cron Expression Builder. Common mistakes:

    • * 2 * * * runs every minute from 02:00 to 02:59, not once at 2am. Use 0 2 * * *.
    • Setting both a day of the month and a day of the week makes cron run when either matches.
    • A schedule like 0 0 31 2 * (31 February) never runs.

    3. Check the server's time zone

    Cron uses the server's clock, which is often UTC. A job set for 0 9 * * * runs at 9:00 UTC, which may be the middle of the night where you are. Check with:

    Terminal
    timedatectl

    4. Use full paths everywhere

    Cron runs with a very short PATH, often just /usr/bin:/bin. Commands like php, node or wp may not be found, and relative file paths are resolved from the user's home folder, not your project. Find the full path with which php and use it, and use full paths for files too. If a script relies on relative paths, change into its folder first:

    crontab
    0 3 * * * cd /home/site/htdocs && /usr/bin/php artisan backup:run >> /home/site/cron.log 2>&1

    5. Load the environment the job needs

    Variables you set in your shell profile, such as API keys or a custom PATH, are not loaded by cron. Either set them at the top of the crontab, or load them in a wrapper script. Also check that the PHP version cron uses matches the one your site uses: on servers with several versions installed, /usr/bin/php may not be the one you expect. On CloudPanel, versioned binaries such as /usr/bin/php8.4 make this explicit.

    6. Check which user runs it

    A job in your personal crontab (crontab -e) runs as you. Jobs in /etc/crontab and /etc/cron.d/ have an extra field naming the user. If the job writes files, it needs permission to write there, and files it creates belong to that user, which can break the website if they are owned by root. On CloudPanel, add cron jobs from the site's Cron Jobs page so they run as the site user.

    7. Make sure cron itself is running

    Terminal
    systemctl status cron
    grep CRON /var/log/syslog | tail -20

    The second command shows recent runs on Debian and Ubuntu (on newer systems without syslog, use journalctl -u cron). If your job does not appear at all, cron is not reading it: check for typos, and make sure the crontab file ends with a newline. Files in /etc/cron.d/ are skipped if their names contain a dot.

    Bonus: jobs that run too long

    If a job sometimes takes longer than the gap between runs, two copies can run at once and get in each other's way. flock skips a run while the previous one is still going:

    crontab
    */5 * * * * /usr/bin/flock -n /tmp/import.lock /usr/bin/php /home/site/import.php >> /home/site/cron.log 2>&1

    Questions

    How do I test a cron job without waiting?

    Set it to run every minute (* * * * *), watch the log, then put the real schedule back. To copy cron's sparse environment in your shell, run the command with env -i /bin/sh -c '...'.

    Should I use cron or a systemd timer?

    Cron is simpler and available everywhere. Systemd timers log every run to the journal and can catch up on runs missed while the server was off. The Cron Expression Builder gives you the timer version of any schedule.

    Use the linked tools to confirm each change, then repeat the original test. Review server or DNS changes before applying them to a live site.

    Spotted something out of date? Email [email protected].

    More guides

    Technical SEO5 min read

    Crawling versus indexing

    Check response directives and discovery, then consult the search engine’s recorded indexing reason.

    Email5 min read

    Set up email DNS

    Separate receiving records from sending authentication and verify every legitimate sender.

    Network5 min read

    Why a port check says closed

    Trace the connection path without disabling the firewall or treating a TCP result as a UDP test.

    Redirects7 min read

    Fix ERR_TOO_MANY_REDIRECTS

    The usual causes are a CDN in Flexible SSL mode, a wrong site address in your CMS or two rules that disagree about www.

    Email9 min read

    Emails going to spam

    Read receiving-server headers, check authentication and alignment, then investigate reputation and recipient signals.

    DNS6 min read

    DNS change not showing up

    Compare authoritative records and resolver caches to investigate a DNS change that has not appeared.

    ↑ ↓ moveEnter openEsc close

    Expanded view