Skip to main content
Linux Server Administration · 8 min read

A cron job that works perfectly when you paste it into a shell and does nothing when cron runs it is one of the most common time-wasters in server administration. The cause is almost never cron itself. It is nearly always that cron runs your command in a much barer world than your interactive shell.

Start With the Question: Did Cron Even Try?

Before touching the script, find out whether cron attempted to run it. Distinguishing “cron never launched it” from “cron launched it and it failed” cuts the search space in half.

On most distributions, cron logs each launch either to the system journal or to a syslog file. Check the cron service’s log entries around the time the job should have fired. On systemd-based systems, journalctl -u cron or journalctl -u crond (the unit name varies by distribution) is the usual place. You are looking for a line naming your user and your command.

If there is no line at all, the problem is in scheduling or parsing. If there is a line, the problem is in execution, and you can stop staring at the schedule.

When Cron Never Launched It

A few causes account for most of these cases:

  • A syntax slip in the crontab. Five time fields, then the command. A missing field or a stray character can make the whole line invalid. Files in /etc/cron.d/ additionally require a username field before the command, which per-user crontabs do not have.
  • A missing trailing newline. Some cron implementations ignore the last line if the file does not end in a newline.
  • The wrong crontab. Editing root’s crontab while the job needs another user’s, or editing a file in /etc/cron.d/ with permissions or a filename that cron skips. Many implementations ignore files with certain characters in the name or with unsafe ownership.
  • The service is not running. Rare, but worth ten seconds to confirm.
  • Percent signs. In a crontab, an unescaped % is treated as a newline and truncates the command. Date formatting such as date +%F must be written with the percent signs escaped by backslashes.

When Cron Launched It and It Failed

This is the bigger bucket, and the culprit is almost always the environment. Cron starts jobs with a minimal environment: a short default PATH, a simple shell, no login profile, and none of the variables your session has set.

Common consequences:

  1. Commands not found. node, python3 from a version manager, or anything installed in a user directory is not on cron’s PATH. Use absolute paths to every binary, or set PATH at the top of the crontab.
  2. Relative paths break. Cron’s working directory is typically the user’s home, not your project. Either cd into the right directory inside the command or use absolute paths throughout.
  3. Missing environment variables. Secrets and configuration exported in your shell profile are not there. Load them explicitly from a file the script reads, with sensible permissions.
  4. Shell differences. Cron usually runs commands with /bin/sh, which may be a minimal shell. A script relying on bash features should have a proper shebang and be called directly, or the crontab should set SHELL.
  5. Permissions. The script must be executable by the user the job runs as, and every directory it writes to must be writable by that user.

Capture the Output You Are Currently Throwing Away

Cron’s default behavior for output is to mail it to the job’s owner, which on most servers goes nowhere because no mail system is configured. So errors vanish. The fix is to redirect output yourself while debugging:

*/5 * * * * /usr/local/bin/sync-reports.sh >> /var/log/sync-reports.log 2>&1

The 2>&1 matters: without it, error messages (stderr) are not captured. Run it once at the next interval and read the log. Nine times out of ten the real error message is sitting there, and it says “command not found” or “permission denied.”

A Troubleshooting Checklist

SymptomLikely causeFirst check
No log line from cron at allSyntax error, wrong file, service downCron service status and crontab syntax
Log line present, no effectEnvironment or PATHRedirect output to a file
“command not found”Minimal PATHUse absolute binary paths
“permission denied”Script or target not accessible to that userOwnership and execute bit
Works at the prompt, not in cronMissing variables or different shellRun under a cleared environment
Runs, but date-named files are wrongUnescaped percent signsEscape % in the crontab

A Realistic Example

Imagine a nightly job that exports a report and compresses it with a tool installed under a user’s home directory by a version manager. It has run fine by hand for weeks. After setting it up in cron, no reports appear. There is a cron log line, so the job launches. Redirecting output to a file shows the message that the interpreter is not found. The shell finds it through a profile file that cron never reads. The fix is to call the interpreter by absolute path in the script. While in there, the administrator also adds a line that writes a timestamp on success, so that a missing timestamp tomorrow is itself the alarm.

Frequently Asked Questions

Why does my script work manually but not from cron? Because cron supplies a minimal environment: a short PATH, no profile, a different working directory and often a simpler shell. Use absolute paths, set needed variables explicitly and redirect output to a log to see the actual error.

How do I see the output of a cron job? Append >> /path/to/logfile 2>&1 to the command. By default cron tries to email output, which usually goes nowhere on a server without a mail setup.

Does the order of fields in a crontab matter? Yes. The five time fields are minute, hour, day of month, month and day of week, followed by the command. System crontabs and /etc/cron.d/ files add a username field between the time fields and the command.

Should I use cron or a systemd timer? Both work. Timers integrate with the journal, support dependencies and show status through the same commands as other services. Cron remains simple and universal. Pick one approach per server so people know where to look.

How can I tell if a job silently stopped running weeks ago? You usually cannot, unless you built that in. Have each job record a success timestamp and monitor its age, or use a check-in style monitor that alerts when an expected signal does not arrive.

Next Step

Pick one cron job on your servers that matters, add output redirection to a log file, and add a success marker that your monitoring checks. That single change turns silent failures into visible ones.


By CRMServerBase Editorial · Updated November 4, 2026

  • cron troubleshooting
  • cron jobs
  • Linux scheduling
  • crontab