SystemdDoctor
мешает работе сокеты активация

Служба получает не тот сокет из нескольких

Один сокет может объявлять несколько слушателей, и служба получает их все по порядку. Без имён различить, какой из них какой, можно только по порядку объявления — и любая правка описания ломает работу службы.

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

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

  1. Слушатели не имеют имён

    Служба получает набор описателей и обычно берёт первый. Порядок задаётся описанием, и правка меняет соответствие.

  2. Служба не умеет работать с несколькими описателями

    Многие программы рассчитаны ровно на один переданный сокет. Остальные они игнорируют.

  3. Порядок слушателей изменился при правке

    Добавление строки в начало описания меняет порядок описателей, и служба начинает слушать не то, что нужно.

Диагностика

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

Слушатели и имя набора описателей.

systemctl show myapp.socket -p ListenStream -p FileDescriptorName

Какие порты фактически слушаются.

sudo ss -tlnp | grep -E ":8080|:8443"

Что служба сообщает о полученных сокетах.

journalctl -u myapp.service -n 20 --no-pager

Решение

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

1. Слушатели не имеют имён
Почему происходит
Служба получает набор описателей и обычно берёт первый. Порядок задаётся описанием, и правка меняет соответствие.
Как проверить
Посмотрите объявленные слушатели и имя набора.
systemctl cat myapp.socket | grep -E "^(Listen|FileDescriptorName)"
systemctl show myapp.socket -p FileDescriptorName
Как исправить
Разделите слушатели по отдельным сокетам с именами: тогда служба получит их вместе с именами и порядок перестанет иметь значение.
[Socket]
ListenStream=8080
FileDescriptorName=http
2. Служба не умеет работать с несколькими описателями
Почему происходит
Многие программы рассчитаны ровно на один переданный сокет. Остальные они игнорируют.
Как проверить
Посмотрите число переданных описателей и поведение службы.
systemctl show myapp.socket -p NAccepted -p ListenStream
journalctl -u myapp.service -n 20 --no-pager | grep -iE "listen|fd"
Как исправить
Передавайте службе ровно один слушатель. Если нужны разные порты, делайте отдельные сокеты и отдельные службы.
3. Порядок слушателей изменился при правке
Почему происходит
Добавление строки в начало описания меняет порядок описателей, и служба начинает слушать не то, что нужно.
Как проверить
Сравните порядок в описании и фактическое поведение.
systemctl cat myapp.socket | grep -nE "^Listen"
sudo ss -tlnp | grep -E ":8080|:8443"
Как исправить
Задайте имена наборам описателей: тогда порядок в файле перестанет влиять на работу.

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

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

$ systemctl cat myapp.socket | grep ^Listen
ListenStream=8443
ListenStream=8080

myapp[9300]: listening on inherited fd 3 (expected plain HTTP)
myapp[9300]: TLS handshake failed: first record does not look like a TLS handshake

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

Источники

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