SystemdDoctor
служба не работает частое workingdirectory пути права

status=200/CHDIR в systemd

Код 200/CHDIR systemd выдаёт до запуска программы: он не сумел сделать рабочим каталог, указанный в WorkingDirectory=. Каталога либо нет, либо к нему нет доступа у пользователя службы, либо это вообще не каталог. Сама программа при этом не запускалась.

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

Смена рабочего каталога — один из первых шагов подготовки процесса, и выполняется он уже после перехода на пользователя из User=. Поэтому проверять доступ надо от имени этого пользователя, а не от root: у root доступ есть почти всегда, и это сбивает с толку.

Отдельный случай — каталог на сетевом или отдельном разделе. На момент запуска службы он может быть ещё не смонтирован, и тогда 200/CHDIR появляется только после перезагрузки, а при ручном перезапуске всё работает.

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

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

  1. Каталога не существует

    Опечатка в пути, каталог удалён или ещё не создан при первой установке. systemd сам каталог из WorkingDirectory= не создаёт.

  2. У пользователя службы нет доступа к каталогу

    Для перехода в каталог нужен бит x на нём и на всех каталогах по пути. Частая картина: каталог принадлежит root с правами 0700, а служба работает от отдельного пользователя.

  3. Путь указан относительным

    WorkingDirectory= принимает либо абсолютный путь, либо знак тильды для домашнего каталога пользователя. Запись вида WorkingDirectory=opt/myapp для systemd бессмысленна.

  4. Каталог находится на ещё не смонтированном разделе

    Служба стартует раньше монтирования нужного раздела, и на его месте пока пустая точка монтирования или вообще ничего. После перезагрузки — отказ, при ручном запуске — успех.

  5. Это не каталог, а файл или битая ссылка

    Если по пути оказался обычный файл или символическая ссылка в никуда, переход завершится ошибкой ENOTDIR или ENOENT — код тот же.

Диагностика

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

Подтверждает код 200/CHDIR и показывает, что до строки запуска программы дело не дошло.

systemctl status myapp.service -l --no-pager

systemd печатает «Changing to the requested working directory failed» вместе с путём и причиной от ядра.

journalctl -xeu myapp.service --no-pager -n 30

Показывает действующие значения после всех drop-in — то есть то, что systemd реально применил.

systemctl show myapp.service -p WorkingDirectory -p User

Решение

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

1. Каталога не существует
Почему происходит
Опечатка в пути, каталог удалён или ещё не создан при первой установке. systemd сам каталог из WorkingDirectory= не создаёт.
Как проверить
Проверьте существование пути целиком, а не только последнего каталога.
systemctl cat myapp.service | grep -i workingdirectory
ls -ld /opt/myapp
Как исправить
Создайте каталог и назначьте владельца, от имени которого работает служба. Для каталогов в /var/lib, /var/cache и /run удобнее не создавать их вручную, а поручить systemd через StateDirectory=, CacheDirectory= и RuntimeDirectory=.
sudo install -d -o app -g app -m 0750 /opt/myapp
2. У пользователя службы нет доступа к каталогу
Почему происходит
Для перехода в каталог нужен бит x на нём и на всех каталогах по пути. Частая картина: каталог принадлежит root с правами 0700, а служба работает от отдельного пользователя.
Как проверить
Проверьте доступ именно от пользователя службы.
sudo -u app sh -c 'cd /opt/myapp && echo доступ есть'
Как исправить
Исправьте владельца или права. Осторожнее с chmod -R 777: это снимает проблему и создаёт новую.
sudo chown -R app:app /opt/myapp && sudo chmod 750 /opt/myapp
3. Путь указан относительным
Почему происходит
WorkingDirectory= принимает либо абсолютный путь, либо знак тильды для домашнего каталога пользователя. Запись вида WorkingDirectory=opt/myapp для systemd бессмысленна.
Как проверить
Посмотрите, начинается ли значение с косой черты.
Как исправить
Допишите путь от корня целиком. Относительных путей systemd не разбирает: понятия «текущий каталог» у него в этот момент нет, поэтому дополнять значение нечем.
WorkingDirectory=/opt/myapp
4. Каталог находится на ещё не смонтированном разделе
Почему происходит
Служба стартует раньше монтирования нужного раздела, и на его месте пока пустая точка монтирования или вообще ничего. После перезагрузки — отказ, при ручном запуске — успех.
Как проверить
Сравните время монтирования и время запуска службы в журнале загрузки.
systemctl list-dependencies --before myapp.service
systemctl status data.mount
Как исправить
Добавьте зависимость от точки монтирования. Самый короткий способ — RequiresMountsFor=: systemd сам найдёт нужный mount-unit по пути.
[Unit]
RequiresMountsFor=/opt/myapp
5. Это не каталог, а файл или битая ссылка
Почему происходит
Если по пути оказался обычный файл или символическая ссылка в никуда, переход завершится ошибкой ENOTDIR или ENOENT — код тот же.
Как проверить
Посмотрите тип объекта по пути.
ls -ld /opt/myapp && readlink -f /opt/myapp
Как исправить
Исправьте путь или замените файл настоящим каталогом.

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

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

× myapp.service - My application
     Active: failed (Result: exit-code) since Mon 2026-09-14 12:30:02 MSK; 2s ago
    Process: 5120 ExecStart=/usr/local/bin/myapp (code=exited, status=200/CHDIR)
   Main PID: 5120 (code=exited, status=200/CHDIR)

systemd[5120]: myapp.service: Changing to the requested working directory failed: No such file or directory
systemd[1]: myapp.service: Main process exited, code=exited, status=200/CHDIR
systemd[1]: myapp.service: Failed with result 'exit-code'.

Частые вопросы

Можно ли сделать каталог необязательным?

Да, поставьте дефис перед путём: WorkingDirectory=-/opt/myapp. Тогда при отсутствии каталога systemd не станет считать это ошибкой и запустит программу в корне. Для большинства служб это не то, что нужно, но для одноразовых задач бывает удобно.

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

  • status=203/EXEC в systemd Код 203/EXEC означает, что systemd не смог выполнить программу из ExecStart=. Разбор причин: путь, права, интерпретатор, синтаксис оболочки.
  • status=217/USER в systemd Код 217/USER означает, что systemd не смог определить или сменить пользователя из User=. Разбор причин: пользователя нет, имя недопустимо, конфликт с DynamicUser.
  • Permission denied в журнале службы Отказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
  • status=233/RUNTIME_DIRECTORY в systemd Код 233/RUNTIME_DIRECTORY: не удалось подготовить каталог службы в /run из RuntimeDirectory=. Права, режим, удаление при остановке.
  • No such file or directory в журнале службы Служба не находит файл или каталог. Разбор: путь, момент запуска, изоляция unit-файла, символические ссылки, приватный /tmp.
  • MySQL: Can't open the mysql.plugin table и повреждение системных таблиц MySQL не запускается: недоступны или повреждены системные таблицы. Права на каталог данных, версия схемы, восстановление.
  • PostgreSQL: data directory has invalid permissions Кластер PostgreSQL не запускается из-за прав на каталог данных. Требование 0700 или 0750 и как вернуть владельца.
  • nginx 403 Forbidden и Permission denied на файлы сайта nginx отдаёт 403: нет прав на файлы сайта, закрыт каталог по пути, мешает SELinux или AppArmor, нет индексного файла.

Где встречается чаще всего

Источники

  • systemd.exec(5)
    200 EXIT_CHDIR: «Changing to the requested working directory failed», см. WorkingDirectory=.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено на unit с несуществующим каталогом и на каталоге 0700, принадлежащем root, при User=app.
    собственная проверка, systemd 255
    сверено 15 сентября 2026