Что означает ошибка CRON_ERR
Планировщик cron не выводит единый цифровой код сбоя, подобно Windows. Запись CRON_ERR или сообщения вида (CRON) error в системных логах — это собирательный индикатор того, что демон не смог выполнить запланированное задание или само задание завершилось с ненулевым статусом выхода.
Вы столкнётесь с этой проблемой, когда автоматизированные скрипты перестают выполняться по расписанию, файлы не обновляются, или на вашу почту приходят пустые письма с кодами 1, 126, 127. Ошибка проявляется строго в фоновом режиме, поэтому без явного логирования её легко пропустить до тех пор, пока не накопятся критические последствия.
Причины возникновения
Сбой планировщика почти всегда сводится к одному из следующих факторов:
- Неверные пути в переменной
$PATH. Cron запускает задачи с минимальным окружением, где/usr/local/binили/snap/binмогут отсутствовать. - Отсутствие прав на исполнение. Файл скрипта не имеет бита
+x, или пользователь не добавлен в/etc/cron.allow. - Интерактивные запросы. Скрипт требует ввода пароля, подтверждения
sudoили вывода в терминал, что невозможно в фоновом демоне. - Гонка ресурсов и блокировки. Два задания пытаются одновременно писать в один лог-файл или базу данных без механизма
flock. - Повреждение таблиц crontab. Невалидный синтаксис строки (например, пробел вместо табуляции или пропущенное поле минут) заставляет парсер отбрасывать задачу целиком.
Способы решения
Способ 1: Проверка состояния и перезапуск службы
Первым делом убедитесь, что сам демон планировщика работает штатно. В зависимости от дистрибутива служба называется cron (Debian/Ubuntu) или crond (RHEL/AlmaLinux).
# Проверка статуса (Ubuntu/Debian)
systemctl status cron
# Проверка статуса (RHEL/CentOS/Alma)
systemctl status crond
Если вывод показывает inactive (dead) или failed, запустите службу и добавьте её в автозагрузку:
sudo systemctl enable --now cron # или crond
💡 Совет: Если служба падает сразу после запуска, проверьте синтаксис всех пользовательских файлов через
crontab -e— один некорректный символ может блокировать загрузку демона.
Способ 2: Чтение системных логов и отладка вывода
Стандартные ошибки cron записываются в syslog или journal. Отберите события за последний час, чтобы найти точную строку сбоя:
journalctl -u cron --since "1 hour ago" | grep -i error
Для отладки конкретной задачи временно перенаправьте её стандартный вывод и поток ошибок во временный файл. Добавьте в конец строки crontab конструкцию >> /tmp/task_debug.log 2>&1:
*/5 * * * * /opt/scripts/backup.sh >> /tmp/cron_debug.log 2>&1
После срабатывания расписания откройте /tmp/cron_debug.log — там будет точный текст ошибки, который выдал ваш скрипт.
Способ 3: Настройка переменных окружения и абсолютных путей
Самая частая причина кода 127 (command not found) — отсутствие полных путей. Cron не наследует ваш .bashrc или .profile.
- Откройте таблицу задач:
crontab -e - В самое начало файла добавьте явную переменную окружения:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SHELL=/bin/bash
- Замените относительные вызовы на абсолютные. Вместо
python3 script.pyиспользуйте/usr/bin/python3 /home/user/scripts/task.py.
Способ 4: Проверка списков доступа и блокировочных файлов
Если в логах появляется (username) ACCESS DENIED, проверьте конфигурацию контроля доступа.
# Проверка существования файлов контроля
ls -la /etc/cron.allow /etc/cron.deny 2>/dev/null
- Если существует
/etc/cron.allow, в него должен быть записан ваш пользователь. Файлcron.denyпри этом игнорируется. - Если файлов нет, доступ открыт всем, кроме
root(в некоторых дистрибутивах) и пользователей с оболочкой/sbin/nologin.
Для предотвращения конфликтов нескольких экземпляров используйте flock прямо в строке crontab:
0 2 * * * /usr/bin/flock -n /tmp/backup.lock /opt/scripts/backup_daily.sh
Флаг -n гарантирует мгновенный выход без запуска, если предыдущая задача ещё выполняется.
Профилактика
- Всегда используйте полные пути к бинарникам и скриптам. Не полагайтесь на переменные окружения пользователя.
- Настройте
MAILTOили перенаправление логов в отдельную директорию/var/log/cron_tasks/. Это позволит отслеживать статус выполнения без ручного входа на сервер. - Избегайте
sudoвнутри crontab. Запускайте задачи от нужного пользователя черезsudo -u username crontab -eили настраивайтеsudoersс опциейNOPASSWD. - Регулярно проверяйте расписания командой
crontab -lпосле внесения изменений. Ошибка в одной запятой может сдвинуть запуск на месяц. - Для сложных задач с зависимостями рассмотрите переход на
systemd timers— они предоставляют лучшую изоляцию окружения и встроенные механизмы перезапуска при сбоях.