Job for … failed because a timeout was exceeded
Сообщение «Job for myapp.service failed because a timeout was exceeded» появляется в ответ на команду запуска: systemd ждал TimeoutStartSec= и прекратил ждать. Причина либо в действительно медленном запуске, либо в том, что служба заблокирована и не завершит его никогда.
Что это значит
Первый вопрос — сколько служба стартует в норме. Если обычно это 10 секунд, а сейчас не уложилась в 90, увеличивать таймаут бессмысленно: она заблокирована. Если же она всегда стартует три минуты, таймаут просто занижен.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Служба ждёт внешнего ресурса
Недоступная база, неответчивый сервер имён, сетевая файловая система в режиме жёсткого монтирования — всё это блокирует запуск на минуты.
-
Запуск действительно долгий
Базы данных с восстановлением журнала, службы с прогревом кеша, миграции при старте занимают минуты по своей природе.
-
Тип службы не соответствует поведению программы
При
Type=notifysystemd ждёт уведомления о готовности, приType=forking— завершения исходного процесса. Если программа так себя не ведёт, ожидание не закончится никогда. -
Служба ждёт ввода
Программа спрашивает пароль или подтверждение и ждёт ответа, которого в службе быть не может. Внешне это выглядит как зависание при старте.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Показывает задания, которые ещё выполняются: видно, что именно висит.
systemctl list-jobsКто дольше всех стартовал: помогает понять, нормальное ли это время для службы.
systemd-analyze blame | head -12Последние строки перед таймаутом обычно показывают, на чём служба остановилась.
journalctl -xeu myapp.service --no-pager -n 40Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Недоступная база, неответчивый сервер имён, сетевая файловая система в режиме жёсткого монтирования — всё это блокирует запуск на минуты.
- Как проверить
-
Посмотрите, чем занята служба в момент ожидания.
systemctl list-jobs sudo ss -tnp | grep myapp PID=$(systemctl show -p MainPID --value myapp.service); sudo cat /proc/$PID/wchan 2>/dev/null; echo
- Как исправить
-
Уберите блокирующую зависимость или сделайте её необязательной. Для сетевых каталогов используйте мягкое монтирование и
RequiresMountsFor=, для сервера имён — таймауты в настройках.
- Почему происходит
- Базы данных с восстановлением журнала, службы с прогревом кеша, миграции при старте занимают минуты по своей природе.
- Как проверить
-
Посмотрите, сколько занимал запуск раньше.
systemd-analyze blame | grep myapp journalctl -u myapp.service --no-pager | grep -iE "started|starting" | tail -6
- Как исправить
-
Увеличьте
TimeoutStartSec=с запасом относительно нормального времени.sudo systemctl edit myapp.service # TimeoutStartSec=600
- Почему происходит
- При
Type=notifysystemd ждёт уведомления о готовности, приType=forking— завершения исходного процесса. Если программа так себя не ведёт, ожидание не закончится никогда.
- Как проверить
-
Посмотрите тип и что делает программа.
systemctl show myapp.service -p Type -p NotifyAccess -p PIDFile
- Как исправить
-
Приведите тип в соответствие: для обычной программы на переднем плане —
simpleилиexec.
- Почему происходит
- Программа спрашивает пароль или подтверждение и ждёт ответа, которого в службе быть не может. Внешне это выглядит как зависание при старте.
- Как проверить
-
Поищите в журнале приглашение ко вводу.
journalctl -u myapp.service -n 30 --no-pager | tail -15
- Как исправить
-
Уберите интерактивность: передавайте пароли через
LoadCredential=, а подтверждения — ключами командной строки.
Пример вывода
Команда запуска прервана по таймауту. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ sudo systemctl start myapp.service
Job for myapp.service failed because a timeout was exceeded.
See "systemctl status myapp.service" and "journalctl -xeu myapp.service" for details.
systemd[1]: myapp.service: start operation timed out. Terminating.
systemd[1]: myapp.service: Failed with result 'timeout'.
Связанные ошибки
- Failed with result 'timeout' Состояние timeout: служба не уложилась в отведённое время при запуске, остановке или перезагрузке настроек.
- Failed with result 'protocol' Состояние protocol: служба нарушила договор со systemd. Обычно Type=notify без уведомления или Type=dbus без имени на шине.
- signal=TERM (status=15/TERM) в systemd Процесс службы завершён сигналом TERM. Когда это нормальная остановка, а когда признак проблемы.
- Connection refused в журнале службы Соединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- A start job is running: загрузка висит на одной службе Загрузка останавливается с обратным отсчётом: служба не укладывается в таймаут. Как найти виновника и не ждать.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Exec format error при запуске службы Ошибка формата исполняемого файла: не та архитектура, нет строки #!, повреждённый файл или попытка запустить не программу.
- Python-служба: ModuleNotFoundError при запуске Служба не находит модули: другое виртуальное окружение, неверный интерпретатор, отсутствующие зависимости.
Где встречается чаще всего
Источники
-
systemd.service(5)
TimeoutStartSec= и поведение при истечении срока. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено службой с обращением к недоступной базе при запуске.