239

If I setup cron jobs incorrectly they appear to silently fail. Where should I look for an error log to understand what went wrong?

11 Answers 11

138

As others have pointed out, cron will email you the output of any program it runs (if there is any output). So, if you don't get any output, there are basically three possibilities:

  1. crond could not even start a shell for running the program or sending email
  2. crond had troubles mailing the output, or the mail was lost.
  3. the program did not produce any output (including error messages)

Case 1. is very unlikely, but something should have been written in the cron logs. Cron has an own reserved syslog facility, so you should have a look into /etc/syslog.conf (or the equivalent file in your distro) to see where messages of facility cron are sent. Popular destinations include /var/log/cron, /var/log/messages and /var/log/syslog.

In case 2., you should inspect the mailer daemon logs: messages from the Cron daemon usually appear as from root@yourhost. You can use a MAILTO=... line in the crontab file to have cron send email to a specific address, which should make it easier to grep the mailer daemon logs. For instance:

[email protected]
00 15 * * *  echo "Just testing if crond sends email"

In case 3., you can test if the program was actually run by appending another command whose effect you can easily check: for instance,

00 15 * * * /a/command; touch /tmp/a_command_has_run

so you can check if crond has actually run something by looking at the mtime of /tmp/a_command_has_run.

6
  • 7
    Do these "emails" go in a file also? I'm using shared web hosting and don't think they'd know where to email me. Aug 13, 2013 at 15:59
  • 3
    I appreciate the advice in case 3 to check if the command is even running. In my case, cron wasn't running my job because I had recently changed the server's timezone and needed to restart the cron server so it would evaluate the cron times in the proper timezone.
    – Nathan
    Dec 22, 2013 at 2:20
  • 2
    Depending on your mail transfer agent, you may also find undelivered mails in a file called dead.letter in the root or respective user home directory. Jul 18, 2018 at 13:13
  • What if a cronjob is set to run as a user other than root (username in /etc/crontab just after the time and before the executable path)? I'm getting emails for those run by root, but not from another user.
    – matteo
    Jun 19, 2021 at 18:12
  • Same problem here. It helps running a simple shell script (sh, not bash), move to /tmp directory and launch the command you put in the crontab: you might receive on screen the same errors
    – Raul Luna
    Dec 30, 2021 at 19:45
95

You can always explicitly send the job output to a log file:

0 8 * * * /usr/local/bin/myjob > /var/log/myjob.log 2>&1

Keep in mind that this will supercede the mail behaviour that has been mentioned before, because crond iself won't receive any output from the job. If you want to keep that behaviour you should look into tee(1).

7
  • 36
    Why not use >> instead of >, so you don't overwrite the log file every time?
    – Chris
    Oct 23, 2018 at 1:41
  • 3
    Sure! Any kind of I/O redirection will do, even | /usr/bin/logger if you wish, as cleverly suggested by Stefan. Pick your poison: tldp.org/LDP/abs/html/io-redirection.html
    – codehead
    Apr 18, 2019 at 17:46
  • cron created this log file myjob.log with 0 size as expected, but it logged to another file, where can I change this setting ? Jul 1, 2019 at 4:41
  • What is the menaning of &1 at the end?
    – Čamo
    Jun 15, 2020 at 15:38
  • 1
    @Čamo as mentioned in this SO answer if you had 2>1 the instructions would mean, redirect STDERR to a file name called 1. Since there's a & before the 1 treat the 1 as a file descriptor instead.
    – Ari
    Jun 24, 2020 at 7:17
56

If you aren't seeing the mails, you might be spamming root@yourcompany with the errors which can be quite annoying to the people who use that account for monitoring. Try sending the output to Syslog instead:

*/5 * * * * yourcronjob 2>&1 | /usr/bin/logger -t yourtag

Then, wait for the cronjob to run and look for the error in /var/log/messages (or /var/log/user.log on some systems).

This works great for errors messages which are only 1-2 lines long, such as "yourcronjob: command not found". It also makes use of your existing syslog infrastructure (Logrotation, central syslogging, Splunk, etc.) It also reduces email spam to root.

It may not be a good solution if your cronjob generates hundreds of lines of output.

5
  • 2
    This is really good! I'm using for our Mautic configuration at Lovia. Thanks Stefan! Oct 13, 2020 at 14:44
  • 2
    I still do this, 10 years later! Oct 14, 2020 at 21:24
  • Thanks! FYI: On Ubuntu 20 logs are available in /var/log/syslog.
    – Wirone
    Jan 7, 2021 at 0:42
  • 2
    @Wirone: that file does contain CRON logs, but only the time and invocation line; no output. I have a 2-command crontab entry that runs perfectly from that echoed command line, but the second command doesn't run when cron executes it (the first does). Debugging this has been beyond frustrating. Aug 23, 2021 at 13:23
  • 1
    Where has this been all my life?! May 1, 2022 at 21:19
15

You should get email from crond when the job either fails to run or when the job returns a nonzero exit code. Try typing:

$ mailx

at the command prompt.

mailx(1) is the basic mail reading program on most every Unixlike system. It is very primitive by modern standards, but you can pretty much count on it to always be available. Other, better mail agents may be available, but there are enough of them that you never know which one is installed on some random machine you happen to be using.

Note that unless you have configured your system as an Internet email server, this mail subsystem is used only within the machine. You can send email to and receive from other users on the machine, but you may not be able to send email out to the world, and email from the outer world certainly won't be able to come to your machine.

3
  • sudo apt install -y mailutils May 1, 2022 at 21:01
  • cat /var/mail/$USER to view the messages in batch-mode Jan 9, 2023 at 3:36
  • Also note After you read your mail, mailx automatically places these messages in a storage file called $HOME/mbox Jan 9, 2023 at 3:42
8

The default cron configuration will send you a mail with the output of your program. If this fails, you could try wrapping your failing program in a shell script that ensures that the program does not fail, and you could further log the output.

This is a configurable setting on some cron implementations.

5

Cron logs basic info to /var/log/messages, but mails any program output to the invoking user.

2
  • 6
    There's no /var/log/messages on my Ubuntu server (4.4.0-128-generic #154-Ubuntu SMP). Any idea why? I'va had a few cron jobs defined in root's crontab for months (e.g. apt autoremove), but none seem to have been executed. May 17, 2019 at 4:50
  • On ubuntu, you should look for /var/log/syslog (from here) Mar 31, 2023 at 5:40
2

I stumbled across this thread a few years ago experiencing the same problems and just recently came across a solution to the above mentioned cases by Ricardo. The lack of an email is hard to detect (as you mentioned) and you certainly don't want to spam your root@yourcompany email. If interested check out deadmanssnitch.com.. This tool seems to solve the aforementioned cases. Seems pretty simple to use— just add the bit of code the tool gives you to your cronjob. If your job fails to run at a specified internal, you will be alerted. If you job starts running again you'll also be alerted.

2

Another useful trick is to see what scripts are actually executed.

This is done with run-parts -v --test /etc/cron.hourly/

> /etc/cron.hourly//logrotate

If your script does not show up it will not be executed.

This btw only works for the scripts installed in the /etc/cron.hourly directory. It does not show you items that are set in your crontab.

2

I know it may seem obvious, but it's worth verifying that you can actually run your script manually without Cron. My issue was that the script I was trying to run required authentication. When I ran it manually this was obvious, but I was not getting any email or other indication.

1

I use vixie-cron, so I don't know if this applies to everything. But I have a dead.letter file that contains all the output of the job.

In my /root/ folder I have crons.cron which I set as my crontab by running crontab /root/crons.cron. dead.letter will be created in /root/ as well.

Edit I just Google'd dead.letter, and it's an undeliverable mail. It has nothing to do with cron apparently. If you don't have mail set up correctly (like me), you'll have the file.

1

For newbies, this could be a pain to debug. Be sure not to interchange the minute and the hour values. The minute comes first, then the hour. When you supply values less than 12 for each, it will accept them but may not work as expected or at all.

1
  • 3
    You're right, but I'm not sure this really answers the question. Nov 6, 2018 at 11:23

You must log in to answer this question.

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