What to do when your cron job is not working

By: Shane Harter|Last Updated: Mar 17, 2023

Troubleshooting a failing crontab without being able to reproduce the problem in a terminal can be a painful experience. If your cron job is not working but the command runs successfully when you run it yourself, here are a few steps you can take to help you reproduce the failure by running the command the way cron does.

1. Start with the correct user account

If the cron job is scheduled in your user crontab (e.g. crontab -e) the command will be run as you, not by root.

If the job is in a systemwide crontab like /etc/crontab or a file in /etc/cron.d/ it's allowed to specify a "run as" user between the cron schedule and command. Jobs without an explicit user are run as root. In this example, the job is run as user dataproc:

4 5 * * * dataproc /opt/reporting-snapshot.py

After you determine the user account cron is using to run your job, move on to step 2.

2. Use the right shell

The shell is the application that prints your command prompt and executes your commands. The most common shell in modern linux distributions is bash. If you've logged-in to a linux server you've likely used bash, and when you run a command from your terminal you're asking bash to start the process and display the output. When cron invokes your commands, it uses a different shell by default, /bin/sh and there are a few important differences:

* When you login to a terminal your .bashrc and .bash_profile scripts are executed automatically. This doesn't happen when cron runs your command so any environment variables created here will be missing in your cron jobs. * Bash has special built-ins and features that will cause syntax errors under cron.

Adding a SHELL=/bin/bash declaration at the top of your crontab will give you modern bash features but will not fix problems with .bashrc and .bash_profile

3. Know where to start the job

Cron starts each command from the selected user's home directory. For our dataproc example above, this is /home/dataproc and /root when jobs are run in a system-level crontab without specifying a user.

You can customize the working directory by prepending your command with cd:

4 5 * * * dataproc cd /opt && ./reporting-snapshot.py

4. Putting it all together

Combine these 3 steps in a single command to create an interactive troubleshooting environment for your cron job:

You can customize the working directory by prepending your command with cd:

sudo -u [USER HERE] /bin/sh -c "cd ~ && [COMMAND FROM CRONTAB]"