489

Often, crontab scripts are not executed on schedule or as expected. There are numerous reasons for that:

  1. wrong crontab notation
  2. permissions problem
  3. environment variables

This community wiki aims to aggregate the top reasons for crontab scripts not being executed as expected. Write each reason in a separate answer.

Please include one reason per answer - details about why it's not executed - and fix(es) for that one reason.

Please write only cron-specific issues, e.g. commands that execute as expected from the shell but execute erroneously by cron.

  • 12
    You must close crontab -e for the cron to take affect. For instance using vim I edit the file and use :w to write it but the job is not added to cron until I quit also. So I will not see the job until after I :q also. – DutGRIFF Jun 24 '14 at 14:58
  • I think best way to debug cron is to check syslog and find the problems. – Suneel Kumar Jun 23 '16 at 7:49
  • In my case - the email was going to my SPAM folder, so..... check that before you spend hours on debugging :D – almaruf Nov 6 '17 at 14:54
  • Electricity outages – Josef Klimuk Mar 21 '18 at 7:38

46 Answers 46

2

In 16.04, if you have this error in syslog

(CRON) error (can't fork)

try:

systemctl status cron.service

In the result:

Tasks: num_task (limit: 512)

If num_task is close to the limit use:

systemctl set-property cron.service TasksMax=new_max

Replace new_max with a suitable value.

2

The default .bashrc files on UBuntu 16.04 (and many other versions) have a built in mechanism to not do anything if they are not an interactive shell.

This can prevent the file from being sourced correctly inside a script that is run by cron! To prevent this, comment out the following lines from the top of your .bashrc file:

Ubuntu 16.04

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

Ubuntu 12.04 and some other versions

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

So long as these are left in if cron runs a script which sources your .bashrc file you won't actually get any of the environment variables you are used to inside your terminal!

  • This actually helped me solve my problem after a few hours of debugging. Thank you! – Marek Suscak Feb 4 at 13:49
1

I had a problem with a script that called grep with a regular expression. Some regexs worked when the script was called from crontab while others did not, e.g. [[:print:]] did not work. It turns out that the environment variable LANG has an impact on character sets like [a-z] or [[:print:]]. When I pasted my LANG environment variable into the top of my crontab, i.e. "LANG=en_GB.UTF-8", the grep regular expressions all worked fine when the script was called from crontab. HTH.

1

If crontab mentions something like run-parts /etc/cron.daily, then run-parts may be refusing to run your script. In my case the script in cron.daily did not start with #!/bin/sh.

I discovered this by putting my script in a directory by itself and running run-parts against that directory.

1

This happened to me recently: I had two lines that modified PATH, like this:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/ernesto/bin

Then, later in the file:

PATH=$PATH:/some/other/path

as one would typically do in a shell-interpreted context. However, $PATH seems to not have been expanded, causing all my jobs to fail. The solution is to put everything on a single line.

Edit:

Since I didn't want to wait until the next normal iteration of anacron to verify my jobs worked correctly, I ran:

anacron -fnd "jobname"

Where "jobname" is the job identifier specified in anacrontab. This forces jobs to be run by the same anacron process, sequentially, and without delay.

1

Another Gotcha:

When you type crontab -e and save inside the editor, it won't have any effect. You have to exit the editor for it to add or update according to your changes (e.g. use :x in Vim).

(crontab -e effectively runs "edit cron file; update from cron file" so it's blocking on the editor until you close it.)

1

Logging Permissions

A very simple crontab, won't execute because /var/log/ is not writable by luser account!

* * * * * /usr/local/bin/teamviewer_check >> /var/log/teamviewer.log 2>&1

SOLUTION: create the file as root and chmod to 777

Thanks to the previous suggestion of enabling cron logging in /etc/rsyslog.d/50-default.conf, leads to syslog entry (No MTA installed, discarding output), then thanks to "(CRON) info (No MTA installed, discarding output)" error in the syslog installing postfix in local mode, tail /var/mail/luser, /bin/sh: 1: cannot create /var/log/teamviewer.log: Permission denied

1

Cron jobs won't run if your user's password has expired.

One indication of this is if your cron log (typically /var/log/syslog on Ubuntu, I believe) contains messages like "Authentication token is no longer valid; new one required".

You can check for this problem by running sudo chage -l the_username.

Here's an example of an expired password:

$ sudo chage -l root
Last password change                    : password must be changed
Password expires                    : password must be changed
Password inactive                   : password must be changed
Account expires                     : never
Minimum number of days between password change      : 0
Maximum number of days between password change      : 14600
Number of days of warning before password expires   : 14

The fix is to change the password. For example:

sudo -u root passwd

Then follow the instructions, specifying a new password as prompted.

Thanks to https://serverfault.com/questions/449651/why-is-my-crontab-not-working-and-how-can-i-troubleshoot-it#comment966708_544905 for pointing me in the right direction here. In my case, just as for that commenter, it was the root user of a DigitalOcean box.

1

After hours found out the problem where, I was editing the shell script from Windows (notepad++), where the file was originally located in a Linux server and I've missed out the new line character.

Since I was using Notepad++ to edit the file, I had to do the EOL Conversion to Unix in order to get the new line character, and it worked perfectly.

Hope it helps!

1

Another caveat:

Try not to put your cron scripts in a user's home directory.

I just had a problem where everything seemed good, but just after a while - probably a few hours after I log out, the cron jobs stops working, and these messages appear in the log:

Signature not found in user keyring
Perhaps try the interactive 'ecryptfs-mount-private'

My home directory, at least as far as I know, is not encrypted. But still, moving those scripts outside of the home dir solved the problem.

1

My crontab only worked when I was logged in as user.

I found the solution suggested here on Unix & Linux SE

What was the problem is that the scrips were in my home directory which was encrypted. So it will be unmounted and unavailable when I was logged of. You can use the command mount to see if your home directory is mounted for encryption.

I fixed the problem by putting my scripts in the /usr/local/bin folder.

0

I once was working on a shared server with lots of restrictions.

All the answers here (PATH, SHELL, bash -c,...) could not get my script to work in the crontab.

It did work perfectly when I put the command in a little script file with the PATH, SHELL, and shebang rather than in the crontab itself. I did have to change the permissions to 700.

0

If running scripts within /etc/cron.* directories, make sure your scripts:

  • are executable,
  • match the Ubuntu/Debian cron script namespace (^[a-zA-Z0-9_-]+$).

So for example if you've script with extension (such as .sh) won't work.

To print the names of the scripts which would be run on hourly basis, try:

sudo run-parts --report --test /etc/cron.hourly
0

I had some issues with using sudo in a cron.

Basically I wanted to run a command as a specific user and I tested first, at the command line, su, which returned the error This account is not available. Using sudo, the command ran without errors.

However, when running from cron, the sudo command returned the following error: sudo: sorry, you must have a tty to run sudo.

I later found that using runuser and specifing a shell for the command to run, works.

0

Sometimes cron is working just fine but the script or command you want it to run just fails silently, causing you to bark up the wrong tree.

In such cases I find it useful to wrap the target within another short script, which outputs some visible debugging code (including output of date) and use redirection to ensure I get some evidence to inspect. If the target is a script, wrapping around a sh -x can help further.

The crontab entry (always edit with crontab -e) could look like this:

00 14 * * * (sh -x /tmp/my_wrapper_script) >> /tmp/debug.log 2>&1

Inspect /tmp/debug.log and its timestamp. If it's empty, non-existent or the timesamp isn't shortly after 14:00 (in this example) you may have a cron issue, otherwise you need to debug the actual target action and cron is working just fine!

0

You used:

*  *  * * * DISPLAY=:0 /path/to/your/app

but it failed because your ~/.dbus directory is owned not by you but by root. Check it:

ls -l ~/.dbus

protected by heemayl May 9 '17 at 3:07

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.