Что означает ошибка exit-code=1 в systemd
Когда вы видите в выводе systemctl status сообщение Main process exited, code=exited, status=1/FAILURE или Service entered failed state, это означает, что процесс службы завершился с нештатным кодом возврата. В Linux код 1 является обобщённым индикатором ошибки: программа запустилась, встретила препятствие и немедленно завершила работу. В отличие от краха (signal 9/11), процесс уходит корректно, но сообщает системе, что не может выполнить свою задачу.
Обычно ошибка появляется сразу после запуска, перезагрузки сервера или после обновления пакетов. Systemd переводит юнит в состояние failed и останавливает последующие попытки запуска, пока вы явно не сбросите статус или не исправите конфигурацию.
Причины возникновения сбоя
Конкретный триггер зависит от службы, но на практике сбой exit-code=1 вызывают следующие факторы:
- Синтаксическая ошибка в конфигурационном файле — опечатка в
.conf,.iniили.yamlфайле, который читает служба. Парсер не может разобрать параметры и завершает работу. - Неправильные права доступа (Permissions) — служба пытается прочитать файл конфигурации или записать лог, но владелец или права (
chmod/chown) не позволяют это сделать. - Отсутствующие зависимости или бинарные файлы — путь к исполняемому файлу в
ExecStart=указан неверно, либо пакет был удалён/повреждён при обновлении. - Конфликт ресурсов — служба пытается занять порт, который уже слушает другой процесс, или не может создать PID-файл в
/run/. - Нарушение ограничений безопасности — AppArmor, SELinux или
systemd-ограничения (ProtectSystem=,NoNewPrivileges=) блокируют легитимное действие процесса.
Способы решения
Способ 1: Глубокая диагностика через журнал systemd
Первым делом нужно узнать, что именно не понравилось службе. Полагаться только на вывод systemctl status недостаточно — там обрезаны детали.
- Найдите имя проблемного юнита:
systemctl --failed - Откройте журнал этого юнита, перейдя сразу к последним записям:
sudo journalctl -u <имя_юнита>.service -e --no-pager - Ищите строки, содержащие
error,failed,cannotилиpermission denied. Часто прямо над строкой сstatus=1/FAILUREбудет явное указание, например:Failed to open /etc/myapp/config.yml: Permission denied.
💡 Совет: Если журнал слишком объёмный, ограничьте вывод последними 50 строками:
sudo journalctl -u <юнит> -n 50.
Способ 2: Валидация конфигурации и исправление прав
После того как вы нашли файл, вызывающий ошибку, проверьте его синтаксис и доступы. Для многих служб есть встроенные утилиты проверки.
- Проверьте синтаксис файла службы systemd:
systemd-analyze verify /etc/systemd/system/<имя_юнита>.service - Если служба использует собственный конфиг (например, Nginx, PostgreSQL), запустите его нативную проверку. Пример для Nginx:
sudo nginx -t - Убедитесь, что права соответствуют требованиям. Для большинства демонов нужны права
0644на конфиги и0755на директории:sudo chmod 644 /etc/<путь_к_конфигу>/<файл>.conf sudo chown root:<группа_демона> /etc/<путь_к_конфигу>/<файл>.conf - Перезагрузите конфигурацию systemd, чтобы он подхватил изменения:
sudo systemctl daemon-reload
Способ 3: Сброс состояния и проверка зависимостей
Если конфигурация верна, но служба всё равно не запускается, возможно, systemd «запомнил» предыдущий сбой или не хватает зависимых пакетов.
- Сбросьте счётчик отказов юнита:
sudo systemctl reset-failed <имя_юнита>.service - Проверьте, что не запущен конфликтующий процесс. Например, для порта 80:
Если порт занят, остановите мешающий сервис или изменитеsudo ss -tulpn | grep :80ListenPortв конфигурации. - Запустите службу и сразу отследите её состояние:
Статус должен смениться наsudo systemctl start <имя_юнита>.service systemctl status <имя_юнита>.serviceactive (running). Если ошибка повторяется, вернитесь к журналу: возможно, проблема скрыта в системных библиотеках или нехватке оперативной памяти.
Профилактика
Чтобы ошибки exit-code=1 не появлялись в продакшене, внедрите несколько простых практик:
- Тестируйте конфиги перед перезапуском. Всегда запускайте
nginx -t,httpd -tили аналогичные проверки передsystemctl restart. Это занимает секунды, но экономит часы отладки. - Используйте override-файлы. Не редактируйте стандартные юниты в
/lib/systemd/system/. Создавайте локальные переопределения черезsudo systemctl edit <имя_юнита>.service. Это сохранит ваши настройки при обновлении пакетов. - Мониторьте журналы в реальном времени. Настройте
journald.confдля ротации логов и используйтеjournalctl -fво время деплоя или настройки. - Регулярно обновляйте пакеты. Устаревшие зависимости часто конфликтуют с новыми версиями библиотек. Запускайте
sudo apt update && sudo apt upgrade(или эквивалент для вашего дистрибутива) ежемесячно.