status=2/INVALIDARGUMENT в systemd
Код 2 возвращает сама программа, когда не понимает переданные аргументы. По соглашению LSB это «недопустимые или лишние аргументы». В unit-файлах он чаще всего появляется из-за кавычек и переносов строк, из-за которых программа получает не то, что написано в глазах человека.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Лишние кавычки вокруг аргументов
systemd разбирает строку запуска сам и кавычки снимает по своим правилам. Запись
ExecStart=/usr/bin/app "--opt=a b"даёт один аргумент с пробелом, аExecStart=/usr/bin/app --opt="a b"— аргумент вида--opt=a b. Программа может ожидать другого. -
Аргумент рассчитан на оболочку
Подстановки, звёздочки и переменные вида
$HOMEбез оболочки не раскрываются и уходят программе как текст. Она справедливо считает такой аргумент недопустимым. -
Ошибка в файле настроек, а не в аргументах
Многие программы возвращают 2 и при неверной настройке: неизвестный параметр, недопустимое значение, конфликт разделов.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Показывает разобранную строку запуска: сразу видно, как systemd поделил аргументы.
systemctl show myapp.service -p ExecStartСообщение программы о том, какой аргумент ей не понравился.
journalctl -u myapp.service -n 40 --no-pagerПроверка ожидаемого набора ключей у той версии программы, что установлена.
sudo -u app /usr/local/bin/myapp --help | head -20Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- systemd разбирает строку запуска сам и кавычки снимает по своим правилам. Запись
ExecStart=/usr/bin/app "--opt=a b"даёт один аргумент с пробелом, аExecStart=/usr/bin/app --opt="a b"— аргумент вида--opt=a b. Программа может ожидать другого.
- Как проверить
-
Посмотрите, как systemd разобрал строку: в
systemctl showаргументы видны по отдельности.systemctl show myapp.service -p ExecStart
- Как исправить
-
Убирайте кавычки там, где нет пробелов, и проверяйте разбор через
systemctl show. Для длинных строк используйте переносы с обратной косой.
- Почему происходит
- Подстановки, звёздочки и переменные вида
$HOMEбез оболочки не раскрываются и уходят программе как текст. Она справедливо считает такой аргумент недопустимым.
- Как проверить
-
Поищите в строке запуска символы оболочки.
systemctl cat myapp.service | grep -nE "\*|\$|~"
- Как исправить
-
Передавайте готовые значения или вызывайте оболочку явно:
ExecStart=/bin/sh -c '...'.
- Почему происходит
- Многие программы возвращают 2 и при неверной настройке: неизвестный параметр, недопустимое значение, конфликт разделов.
- Как проверить
-
Запустите встроенную проверку настроек, если она есть, и посмотрите журнал.
journalctl -u myapp.service -n 40 --no-pager
- Как исправить
- Исправьте настройку по сообщению программы: код 2 сам ничего не уточняет.
Пример вывода
Программа получила аргумент вместе с кавычками. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
× myapp.service - My application
Active: failed (Result: exit-code) since Mon 2026-09-15 11:20:12 MSK; 1s ago
Process: 8600 ExecStart=/usr/local/bin/myapp --listen "127.0.0.1:8080" (code=exited, status=2/INVALIDARGUMENT)
myapp[8600]: error: invalid value for --listen: "127.0.0.1:8080"
systemd[1]: myapp.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Связанные ошибки
- status=1/FAILURE в systemd Код 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
- status=203/EXEC в systemd Код 203/EXEC означает, что systemd не смог выполнить программу из ExecStart=. Разбор причин: путь, права, интерпретатор, синтаксис оболочки.
- Коды 64–78 в systemd: набор sysexits Коды 64-78 из sysexits.h: USAGE, DATAERR, NOINPUT, UNAVAILABLE, SOFTWARE, OSERR, CONFIG и другие. Что означает каждый и где смотреть причину.
- Кавычки в ExecStart= разбираются не так, как ожидается Аргументы с пробелами и кавычками: как systemd делит строку запуска и почему программа получает не то.
- status=0/SUCCESS, но служба считается упавшей Программа завершилась успешно, а systemctl показывает inactive или failed. Разбор: Type=simple против forking, RemainAfterExit, демонизация.
- status=126 в systemd: файл не исполняется Код 126: команда найдена, но выполнить её нельзя. Отличие от 127 и от 203/EXEC, разбор причин.
- status=127 в systemd: команда не найдена Код 127 без имени: оболочка не нашла команду. Появляется, когда ExecStart запускает скрипт или sh -c, а внутри команды нет.
- status=200/CHDIR в systemd Код 200/CHDIR означает, что systemd не смог перейти в каталог из WorkingDirectory= до запуска программы. Причины и решение.
Источники
-
systemd.exec(5)
Класс LSB: код 2 — недопустимые или лишние аргументы. -
systemd.service(5)
Правила разбора строки запуска и кавычек в Exec*=. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено на unit с кавычками вокруг значения ключа.