o
A cronjob that does not run often goes unnoticed for days. The causes are almost always the same. This page goes through them in order, split by the two ways a cronjob gets started.
Route 1
On most Linux systems it is called cron, on some crond. If it does not say "active (running)", no job starts at all.
systemctl status cron
Every user has their own crontab. An entry you created as root is invisible to a normal user, and vice versa. Also, the last line needs a line break, otherwise it is ignored.
crontab -l sudo crontab -l -u www-data
This is the most common cause of all. Cron starts with an almost empty environment: a short PATH, no .bashrc, a different working directory. What works in the terminal fails in cron. So write out every path in full, including the one to php.
*/5 * * * * /usr/bin/php /var/www/projekt/cron.php
Error messages otherwise vanish. Redirect both output and errors into a file for a while. After the next run it will say what is failing.
*/5 * * * * /usr/bin/php /var/www/projekt/cron.php >> /tmp/cron.log 2>&1
In a crontab % means a line break. A command such as date +%Y-%m-%d therefore breaks off halfway. Write \%, or put the command into a script of its own.
Cron works in the server's time zone. If that is UTC, a job for 3 am runs at 5 am German time in summer. date shows the server's time. How to write a schedule correctly is explained in the crontab reference.
Route 2
A service like Cronjob.de calls your script through an address. The most important clue is then the HTTP status code your server returns. You find it in the cronjob's call log, together with the runtime and the start of the response.
| Code | Means | What to do |
|---|---|---|
| 401 | Login required | Directory protection sits in front of the script. Store user name and password in the cronjob, or exclude the path from the protection. |
| 403 | Access denied | Almost always a firewall, a security plugin or your host's bot protection, not your script. Our calls carry the user agent Cronjob.de; ask your host to add an exception for it. Also check whether your own script returns 403 for a wrong key. |
| 404 | Address not found | A typo in the address, the file lives elsewhere, or a redirect leads nowhere. Open the address in a browser exactly as it is stored in the cronjob, including with or without www. |
| 500 | Error in the script | Your script crashed. The cause is in the web server or PHP error log, usually found in your host's control panel under "Logs". Common: a missing path, because the script starts in a different directory when called from outside. |
| 502 / 503 / 504 | Server overloaded or too slow | The web server or an upstream service did not answer in time. If it only happens at certain times, too many tasks run at once then. Move the job to a quieter minute or split the work. |
No caller waits forever. At Cronjob.de it is 45 seconds on the free plan and 60 seconds on the paid ones; then we hang up. If the log shows a runtime right at this limit, that was the reason. Split the work into smaller chunks that run more often. With ignore_user_abort(true) a PHP script keeps working at most hosts after the hang-up, until their own time limit kicks in.
We follow redirects, for example from http to https or to www. For POST calls this is tricky: depending on the kind of redirect, the method and the data sent along may not arrive unchanged. So enter the final address right away.
Addresses such as localhost, 127.0.0.1 or 192.168.… exist only in your own network. A service on the internet cannot call them, which is why Cronjob.de does not accept them at all. The same applies to a page that only lives in a company network or behind a VPN.
The trickiest case
The log shows success, but the task is not done. Then it pays to look at the response itself.
A page cache or an upstream network such as Cloudflare serves a stored copy without your script even starting. Exclude the cron address from caching. A runtime of a few milliseconds is a clear hint.
If the address returns your system's login form instead of your output, the status is still 200. The call then needs a key in the address or a login with user name and password.
Print a fixed word at the end of the script, for example OK. If it appears in the response, the script ran to the end. If it is missing, it stopped earlier, and the output before it usually shows where.
If a run takes longer than the gap to the next one, two run at the same time and mails go out twice. A lock at the start of the script prevents this: create a file at the start, delete it at the end, and do not start while it exists.
Cronjob.de logs every call with status, runtime and the start of the response, and emails you on request when a call fails. Five cronjobs are free forever.
Start for free See features