632

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.

5
  • 18
    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, 2014 at 14:58
  • I think best way to debug cron is to check syslog and find the problems. Jun 23, 2016 at 7:49
  • Electricity outages Mar 21, 2018 at 7:38
  • Please check this one askubuntu.com/a/1223213/297387
    – Vadim
    Apr 1, 2020 at 16:15
  • Just one issue, which causes me some time to find out: I had '0 * * * * /pathtoscript/script'. What I have overseen is that the script was not working in teh expected folder. A simple 'cd /pathtoscript' solved my issues. ... took me some hours
    – BerndGit
    Feb 20, 2022 at 15:03

47 Answers 47

1
2
2

On my RHEL7 servers, root cron jobs would run, but user jobs would not. I found that without a home directory, the jobs won't run (but you will see good errors in /var/log/cron). When I created the home directory, the problem was solved.

2

If you edited your crontab file using a windows editor (via samba or something) and it's replaced the newlines with \n\r or just \r, cron won't run.

Also, if you're using /etc/cron.d/* and one of those files has a \r in it, cron will move through the files and stop when it hits a bad file. Not sure if that's the problem?

Use:

od -c /etc/cron.d/* | grep \r
0
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!

1
  • This actually helped me solve my problem after a few hours of debugging. Thank you! Feb 4, 2019 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

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
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
0

Crontab Permissions

There are two files that control the permissions for crontab: /etc/cron.allow and /etc/cron.deny. If there is a cron.allow file, then the user or users that need to use cron will need to be listed in the file. You can use cron.deny to explicitly disallow certain users from using cron.

If neither files exist, then only the super user is allowed to run cron.
Well, that depends on the system specific configuration to be exact. Most configuration do not allow any users to run jobs, while some systems allow all users to run jobs by default.

1
2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .