Сообщение no live upstreams while connecting to upstream в Nginx почти всегда означает одно: в момент обработки запроса сервер считает, что у него нет ни одного доступного backend-узла, куда можно передать трафик. Это может быть PHP-FPM, Gunicorn, Node.js, Apache за reverse proxy или любой другой upstream.
На Debian и Ubuntu ошибка часто всплывает после обновлений, смены версии PHP, правок путей к сокетам, неудачных перезапусков сервисов и изменений в конфигурации upstream. Само сообщение указывает не на причину, а на итог: все backend'ы либо недоступны физически, либо помечены Nginx как «упавшие».
Хорошая новость в том, что в большинстве случаев проблема диагностируется быстро, если идти по чек-листу. Ниже разберём типовые сценарии и безопасный порядок восстановления без гадания и лишних изменений в боевой конфигурации.
Обычно ошибка встречается в трёх схемах:
- Nginx + PHP-FPM через Unix socket или TCP-порт;
- Nginx как reverse proxy до локального или удалённого приложения;
- Nginx с блоком
upstream, где backend'ов несколько и часть из них выведена из пула.
Даже если backend всего один, для Nginx это всё равно пул. Если единственный сервер признан нерабочим, «живых» upstream больше не остаётся, и вы видите именно это сообщение.
Главный принцип диагностики простой: сначала проверяем, жив ли backend и совпадает ли его фактический адрес с тем, что прописано в Nginx. Только потом имеет смысл копаться в
fail_timeout,max_failsи логике балансировки.
С чего начать диагностику
Первое место, куда нужно смотреть, — журнал ошибок Nginx. Обычно рядом с фразой while connecting to upstream есть полезный контекст: путь к сокету, IP-адрес, порт или имя хоста. Это сразу сужает поиск.
sudo tail -n 100 /var/log/nginx/error.log
sudo journalctl -u nginx -n 100 --no-pager
Чаще всего рядом встречаются такие сообщения:
connect() to unix:/run/php/php8.2-fpm.sock failedconnect() failed (111: Connection refused)host not found in upstreamupstream timed outno live upstreams while connecting to upstream
Сразу после этого проверьте синтаксис и итоговую конфигурацию Nginx:
sudo nginx -t
sudo nginx -T
Команда nginx -T особенно полезна, если проблема сидит не в том файле, который вы редактировали, а в другом include из sites-enabled, conf.d или шаблоне панели.
Сценарий №1: PHP-FPM socket не существует или недоступен
Для Debian и Ubuntu это самый частый случай. В конфиге сайта указан путь вроде unix:/run/php/php8.2-fpm.sock, но PHP-FPM либо не запущен, либо слушает другой сокет, либо сокет существует, но Nginx не может к нему подключиться из-за прав.
Проверьте состояние PHP-FPM:
systemctl status php8.2-fpm --no-pager
journalctl -u php8.2-fpm -n 100 --no-pager
Затем проверьте, есть ли сокет и кто его создал:
ls -l /run/php/
ss -xl | grep php
Типичный сценарий после обновления: раньше сайт работал через php8.1-fpm.sock, а после смены версии PHP сервер слушает уже другой сокет, но fastcgi_pass в Nginx остался старым.
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_read_timeout 60s;
}
Теперь сверьте это с фактической настройкой пула:
grep -R "^listen =" /etc/php/8.2/fpm/pool.d/
grep "^listen =" /etc/php/8.2/fpm/pool.d/www.conf
Если путь не совпадает, исправьте либо fastcgi_pass в Nginx, либо параметр listen в пуле PHP-FPM. После изменений примените конфигурацию:
sudo systemctl restart php8.2-fpm
sudo nginx -t
sudo systemctl reload nginx
Отдельно проверьте права на сокет. На Debian и Ubuntu Nginx обычно работает от пользователя www-data. Если сокет принадлежит другому пользователю или группе, подключение не состоится.
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
Если используются отдельные пулы под сайты, ошибка часто возникает после ручной смены пользователя пула без корректировки владельца сокета.
Когда полезно временно перейти с socket на TCP
Если нужно быстро понять, проблема именно в Unix socket или в самом PHP-FPM, можно на время перевести пул на локальный TCP-порт. Это удобный диагностический шаг, особенно когда есть сомнения в правах, окружении /run или политике безопасности системы.
listen = 127.0.0.1:9000
fastcgi_pass 127.0.0.1:9000;
Если после такого переключения сайт оживает, почти наверняка проблема была в пути к сокету или в правах доступа к нему.
Сценарий №2: backend на порту не слушает или слушает не там
Для reverse proxy это второй по популярности случай. Например, Nginx проксирует запросы на 127.0.0.1:3000, а приложение после обновления стало слушать 127.0.0.1:8080, только IPv6-адрес или вообще не стартовало после перезагрузки.
Проверки здесь прямолинейные:
ss -ltnp
systemctl status myapp --no-pager
journalctl -u myapp -n 100 --no-pager
Если backend задан по имени хоста, проверьте ещё и резолвинг:
getent hosts backend
getent ahosts backend
Пример простой схемы reverse proxy:
upstream app_backend {
server 127.0.0.1:3000 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
server_name example.test;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Если приложение недоступно, Nginx несколько раз пытается соединиться. После достижения порога max_fails сервер может быть помечен как нерабочий на период fail_timeout. При одном backend это означает, что доступных узлов не остаётся совсем.
На одиночном приложении слишком жёсткие значения отказоустойчивости нередко вредят больше, чем помогают. Пользователь получает шквал 502 или 504, хотя сервис восстановился бы через несколько секунд.

Как на самом деле работают fail_timeout и max_fails
max_fails — это число неудачных попыток за интервал fail_timeout. Если лимит превышен, сервер помечается как недоступный на тот же период.
upstream backend {
server 127.0.0.1:8080 max_fails=2 fail_timeout=15s;
}
Если в течение 15 секунд Nginx дважды не смог подключиться к backend, он исключит его ещё на 15 секунд. При одном сервере это и даёт no live upstreams.
Практический вывод такой:
- для одиночного backend не задавайте слишком агрессивные значения без явной причины;
- не пытайтесь лечить падение приложения только параметрами Nginx;
- если backend часто перезапускается, сначала исправляйте причину рестартов.
Сценарий №3: upstream задан по имени, но DNS работает не так, как ожидается
Такое часто встречается в контейнерных окружениях, внутренних сетях и схемах с локальными DNS-именами. Проблема в том, что Nginx не всегда переопрашивает DNS так, как это ожидает администратор. Если имя перестало резолвиться или сменился IP, backend внезапно становится недоступным.
Проверьте, что hostname корректно разрешается именно с машины, где работает Nginx:
getent hosts app.internal
resolvectl query app.internal
Если в proxy_pass используются переменные или требуется динамическое разрешение имён, проверьте наличие корректного resolver в конфиге. Отдельно убедитесь, что backend не слушает только IPv4 при попытке подключения по IPv6, или наоборот.
Если вы переносили проект между серверами или меняли сетевую схему, полезно заодно проверить, не осталось ли старых адресов и временных маршрутов. В похожих сценариях помогает материал про миграцию сайта без простоя, где такие расхождения часто всплывают заранее.
Сценарий №4: backend живёт нестабильно из-за systemd, лимитов или crash loop
Иногда Nginx сообщает только следствие, а настоящая проблема находится в самом приложении. Оно может периодически падать, получать OOM, долго стартовать после деплоя или упираться в лимиты systemd.
systemctl status nginx php8.2-fpm myapp --no-pager
journalctl -xeu myapp --no-pager
systemctl show myapp -p Restart -p RestartSec -p StartLimitBurst -p StartLimitIntervalUSec
Если приложение регулярно умирает под нагрузкой, ищите:
- ошибки памяти и OOM в
journalctlиdmesg; - нехватку файловых дескрипторов;
- ошибки доступа к временным каталогам, сокетам и каталогам runtime;
- слишком агрессивные внешние проверки доступности;
- долгий старт приложения после релиза.
Особенно неприятен случай, когда backend стартует медленно, а Nginx начинает слать в него трафик сразу. За несколько неудачных попыток узел помечается как «мёртвый», и даже после запуска приложение ещё какое-то время остаётся вне игры.
Пошаговый runbook для быстрого восстановления
Если инцидент уже в продакшене и сайт нужно вернуть как можно быстрее, используйте короткий порядок действий:
- Откройте журнал Nginx и выясните, к чему именно он пытается подключиться: сокету, IP, порту или hostname.
- Проверьте, жив ли backend: статус systemd, наличие сокета, прослушивание порта.
- Сверьте адрес в Nginx с реальным адресом backend.
- Проверьте права на Unix socket, если используется PHP-FPM.
- Убедитесь, что имя backend корректно резолвится и в нужное семейство адресов.
- Оцените настройки
max_failsиfail_timeout. - После исправления перезапустите backend, выполните
nginx -tи только потом делайте reload Nginx.
sudo systemctl restart php8.2-fpm
sudo nginx -t
sudo systemctl reload nginx
Если приложение работает на отдельном порту, проверьте доступность именно с машины Nginx:
nc -zv 127.0.0.1 3000
curl -I 127.0.0.1:3000
Для Unix socket прямой HTTP-проверки не будет, поэтому ориентируйтесь на наличие файла, его права и журналы запуска PHP-FPM.
Типовые ошибки в конфиге
На практике чаще всего виноваты не редкие баги, а простые расхождения между конфигурацией и реальным состоянием сервисов:
- в
fastcgi_passуказан сокет старой версии PHP; - в блоке
upstreamпрописан порт, который приложение больше не использует; - после деплоя изменилось имя systemd-сервиса, а backend перестал стартовать;
- сокет создаётся в нестандартном месте, но Nginx ищет его в
/run/php/; - backend слушает только
127.0.0.1, а Nginx обращается к::1или наоборот; - хостнейм backend не резолвится или резолвится в неправильный адрес;
- единственный backend слишком быстро исключается из пула из-за настроек отказа.

Что проверить после исправления
Когда ошибка исчезла, важно убедиться, что она не повторится после следующего перезапуска сервера или выкладки.
- проверьте автозапуск backend через
systemctl is-enabled; - убедитесь в корректном порядке старта сервисов после reboot;
- проверьте стабильность пути к сокету в конфигурации PHP-FPM;
- уберите старые include-файлы с устаревшими
fastcgi_passиproxy_pass; - посмотрите журналы Nginx и backend хотя бы несколько минут под рабочей нагрузкой.
systemctl is-enabled nginx
systemctl is-enabled php8.2-fpm
journalctl -u nginx -u php8.2-fpm --since "10 min ago" --no-pager
Если проект критичный, полезно настроить простой health-check, чтобы замечать отказ backend раньше пользователей. Для сайтов на VDS это особенно актуально: вы полностью контролируете systemd, Nginx и модель запуска приложений, а значит можете быстрее локализовать такие сбои.
Практические рекомендации, чтобы ошибка не возвращалась
Для PHP-проектов на Debian и Ubuntu лучший способ снизить риск — унифицировать схему именования сокетов и не оставлять в боевой конфигурации ссылки на старые версии PHP. После каждого обновления сразу проверяйте, что Nginx действительно смотрит в актуальный сокет.
Для reverse proxy под приложения важно, чтобы backend управлялся через systemd, имел понятные параметры перезапуска и стабильно переживал reboot. Если проект растёт и обычного shared-сценария уже мало, стоит сравнить варианты размещения и контроля сервисов, например в разборе про панели управления для VDS.
В распределённых схемах полезно документировать, откуда Nginx берёт адрес backend: из статического IP, внутреннего DNS, контейнерной сети или оркестратора. Чем меньше скрытой магии в адресации, тем проще дальнейшая диагностика.
Если сокет, порт, DNS и systemd проверены, а ошибка остаётся, почти всегда корень проблемы в несовпадении фактической точки прослушивания backend и того, что ожидает Nginx.
Итог
Ошибка no live upstreams while connecting to upstream — это не самостоятельная неисправность, а симптом недоступного backend. В одном случае виноват php-fpm и его сокет, в другом — reverse proxy до неработающего приложения, в третьем — параметры upstream, из-за которых единственный сервер временно исключается из пула.
Чтобы быстро локализовать проблему, двигайтесь от простого к сложному: найдите точный upstream в логах, проверьте его существование и доступность, сверьте конфиг, а уже потом анализируйте таймауты, DNS и политику отказа. Такой подход почти всегда помогает вернуть сайт в работу без хаотичных правок и лишнего простоя.
Если вы размещаете типовые PHP-проекты без сложной собственной инфраструктуры, часть подобных рисков можно снизить на заранее подготовленном окружении, выбрав виртуальный хостинг для простых сайтов или более гибкую серверную схему под отдельные сервисы.


