Find out when a crontab job fails silently

cron runs your command and moves on. If the command fails, the output goes to local mail that nobody reads. If the server is down, or the line was removed, nothing happens at all. Add one curl after the command and you get an email instead.

You need: a Lateping account, shell access to the server, about 5 minutes.

Why cron jobs fail silently

Set it up

  1. Create a check

    Create a check in Lateping with the same cron expression as the job, and set its timezone to the server’s timezone (timedatectl shows it on most Linux systems).

  2. Add the ping to the crontab line

    Edit your crontab with crontab -e:

    crontab
    17 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 5 -o /dev/null https://lateping.com/p/<check-id>
    

    && means the ping runs only if backup.sh exits with status 0. If the script fails, or the line never runs, no ping arrives and the check alerts after the grace period. Replace /usr/local/bin/backup.sh with your own command.

  3. Alert straight away on failure

    Add || curl …/fail to report a failure immediately instead of waiting for the grace period:

    crontab
    17 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 5 -o /dev/null https://lateping.com/p/<check-id> || curl -fsS -m 10 --retry 5 -o /dev/null https://lateping.com/p/<check-id>/fail
    

    The shell reads this left to right. If backup.sh fails, the success ping is skipped and the /fail ping runs. If the script succeeds but the success ping itself cannot get through after its retries, the /fail ping also runs, so a network problem can show up as a failure. That errs on the side of telling you.

What the curl flags do

  • -f: fail on an HTTP error. A wrong check ID returns 404, and curl exits non-zero instead of succeeding quietly.
  • -sS: no progress bar, but still print errors.
  • -m 10: give up on an attempt after 10 seconds, so a network problem never hangs your cron job.
  • --retry 5: retry transient errors up to five times.
  • -o /dev/null: discard the OK response body, so a successful run prints nothing.

cron’s PATH is not your shell’s PATH

cron starts commands with a minimal environment. On many Linux systems PATH is just /usr/bin:/bin. Either use full paths in the script, or set PATH at the top of the crontab:

crontab
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

curl is usually in /usr/bin, so the ping works with the default PATH. Check with command -v curl.

MAILTO

cron emails a job’s output to MAILTO, or to the crontab’s owner if it is not set. Because the ping is silent on success (-sS -o /dev/null), cron output now means something went wrong. If you have working mail, set MAILTO=you@example.com to receive it; if not, Lateping’s alert covers you either way. MAILTO="" turns cron mail off.

Notes

  • % is special in a crontab line: cron turns it into a newline. Escape it as \% if your command needs one, for example in a date format.
  • Set the grace period to longer than the job’s normal run time. Ten minutes is a good start.
  • To record run time, add curl -fsS -m 10 --retry 5 -o /dev/null https://lateping.com/p/<check-id>/start; before the command.
  • Alerts go by email. On Pro and above they can also go to Slack, Discord or a webhook.

Next steps

On this page