Ошибка systemd: Socket service entered failed state — Решение
При использовании механизма Socket Activation управляющий сокет переходит в аварийный режим, а связанный сервис не запускается. В журнале фиксируется ошибка: Socket service entered failed state или Failed to listen on unit socket: Address already in use.
| Компонент | Статус / Ошибка | Причина инцидента |
|---|---|---|
.socket юнит | failed (Result: resources / exit-code) | Порт или сокет-файл уже захвачен другим процессом (EADDRINUSE) |
.service юнит | inactive (dead) | Сервис не получает файловый дескриптор от systemd |
| UNIX сокет-файл | EACCES (Permission denied) | Неверные директивы SocketMode, SocketUser или SELinux блокировка |
- Клиентские подключения к сокету сбрасываются с ошибкой
Connection refused. - Команда
systemctl status <name>.socketотображает:Unit entered failed state. - В логах ядра:
systemd[1]: foo.socket: Unit entered error state: Address already in use.
- Определите, какой сокет вызвал ошибку, и проверьте его текущий статус:
sudo systemctl status *.socket --failed sudo journalctl -xeu <unit_name>.socket - Проверьте, занят ли порт сторонним процессом, работающим в обход systemd:
sudo ss -tulpn | grep <port_number> # Либо для UNIX-сокета: sudo lsof /path/to/socket.sock - Если порт занят монолитным процессом, остановите его и отключите автозагрузку:
sudo systemctl stop <conflicting_standalone_service> sudo systemctl disable <conflicting_standalone_service> - Если сбой касается UNIX-сокета, проверьте права и удалите зависший мертвый файл сокета:
sudo rm -f /run/<socket_name>.sock # Настройте права в секции [Socket] юнита: # SocketMode=0660 # SocketUser=www-data # SocketGroup=www-data - Выполните перезагрузку конфигурации и активируйте сокет заново:
sudo systemctl daemon-reload sudo systemctl restart <unit_name>.socket
sd_listen_fds, либо приложение должно принимать переданный дескриптор, не пытаясь самостоятельно вызывать повторный bind() на тот же порт.Частые вопросы (FAQ)
Что такое Socket Activation в systemd?
Это механизм, при котором systemd заранее создает и слушает сетевой или UNIX-сокет. При поступлении первого входящего пакета systemd мгновенно запускает целевой сервис и передает ему открытый файловый дескриптор.
Почему при запуске .service файла падает .socket файл?
Если в конфигурации .service файла приложение пытается самостоятельно открыть тот же порт (bind), возникает конфликт адреса (Address already in use), так как порт уже занят процессом systemd через .socket юнит.
Как проверить список всех активных сокетов systemd?
Используйте утилиту systemctl list-sockets, которая покажет адреса прослушивания, связанные сервисы и состояние очередей.
Как восстановить упавший сокет без перезагрузки ОС?
Выполните sudo systemctl reset-failed <name>.socket, затем sudo systemctl start <name>.socket.