SystemdDoctor

Found ordering cycle: циклическая зависимость при загрузке

Сообщение «Found ordering cycle on …» значит, что службы требуют запуска друг после друга по кругу. systemd разрывает цикл, произвольно отбрасывая одну связь, и запуск проходит — но не в том порядке, который вы задумывали. Иногда одна из служб при этом вообще не поднимается.

Что это значит

Цикл почти всегда возникает из смешения двух разных понятий. After= задаёт порядок, Requires= задаёт необходимость. Если добавлять их «на всякий случай» в обе стороны, круг возникает сам.

В журнале загрузки systemd печатает всю цепочку: он перечисляет unit, участвующие в цикле, и говорит, какую связь удаляет. Это и есть готовый ответ, где рвать по-настоящему.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. Взаимные After= между двумя службами

    Каждая объявила, что должна стартовать после другой. Одновременно это невыполнимо.

  2. Цикл через цель

    Служба объявила Before=multi-user.target, а цель тянет службу, которая зависит от первой. Цикл идёт через цель и потому не виден при взгляде на две службы.

  3. Цикл через RequiresMountsFor= или автоматические зависимости

    systemd сам добавляет зависимости: службы после локальных файловых систем, точки монтирования после устройств. Собственные связи, направленные против них, замыкают круг.

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Главная команда: печатает цепочку цикла и то, какую связь systemd отбросил.

journalctl -b --no-pager | grep -iE "ordering cycle|breaking ordering|deleting job"

Находит часть проблем с зависимостями без перезагрузки.

systemd-analyze verify myapp.service

Дерево зависимостей: помогает увидеть круг глазами.

systemctl list-dependencies myapp.service --no-pager

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. Взаимные After= между двумя службами
Почему происходит
Каждая объявила, что должна стартовать после другой. Одновременно это невыполнимо.
Как проверить
Найдите цепочку в журнале загрузки.
journalctl -b --no-pager | grep -iE "ordering cycle|breaking ordering" | head -20
Как исправить
Оставьте порядок только в одну сторону — там, где он действительно нужен. Вторую связь уберите.
2. Цикл через цель
Почему происходит
Служба объявила Before=multi-user.target, а цель тянет службу, которая зависит от первой. Цикл идёт через цель и потому не виден при взгляде на две службы.
Как проверить
Постройте дерево зависимостей в обе стороны.
systemctl list-dependencies myapp.service --no-pager | head -20
systemctl list-dependencies --reverse myapp.service --no-pager | head -20
Как исправить
Уберите Before= для цели: включение службы в цель и так обеспечивает нужный порядок через механизм [Install].
3. Цикл через RequiresMountsFor= или автоматические зависимости
Почему происходит
systemd сам добавляет зависимости: службы после локальных файловых систем, точки монтирования после устройств. Собственные связи, направленные против них, замыкают круг.
Как проверить
Посмотрите, какие зависимости добавлены автоматически.
systemctl show myapp.service -p After -p Before | tr " " "\n" | head -30
Как исправить
Не объявляйте порядок относительно системных целей вручную. Для каталога на отдельном разделе достаточно RequiresMountsFor=, остальное systemd достроит сам.

Пример вывода

Две службы объявили порядок друг относительно друга. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.

systemd[1]: Found ordering cycle on backend.service/start
systemd[1]: Found dependency on frontend.service/start
systemd[1]: Found dependency on backend.service/start
systemd[1]: backend.service: Job frontend.service/start deleted to break ordering cycle starting with backend.service/start
systemd[1]: Started backend.service - Backend API.

Последняя строка обманчива: служба запустилась, но зависимость frontend была отброшена, и порядок оказался не тем, что задумывался.

Связанные ошибки

Источники

  • systemd.unit(5)
    After=, Before=, Requires= и автоматические зависимости по умолчанию.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено взаимными After= у двух служб: в журнале видно, какую связь systemd удалил.
    собственная проверка, systemd 255
    сверено 15 сентября 2026