Ошибка 502 Bad Gateway: причины и решение
Что такое ошибка 502 Bad Gateway
Ошибка 502 Bad Gateway — это код ответа HTTP, который отдаёт прокси-сервер (шлюз), когда не может получить корректный ответ от вышестоящего сервера (upstream). Говоря проще: сервер, стоящий перед вашим приложением, честно сообщает — «я обратился к бэкенду, но тот не ответил или ответил мусором».
Классическая связка, в которой возникает 502, — это nginx (или Apache в режиме reverse proxy) перед PHP-FPM, Node.js, Python-приложением или другим веб-сервером. Прокси принимает запрос посетителя, перенаправляет его дальше, а назад получает либо ничего, либо ответ, который не может разобрать. Итог — браузеру уходит 502.
Важно понимать: 502 — это всегда проблема на стыке двух серверов. Сам прокси обычно жив и работает, а вот тот, кто за ним, — нет. Это отличает 502 от ошибки 500, где проблема внутри самого приложения, и от 503, где сервер осознанно сообщает о временной недоступности.
Что видит пользователь
Тексты в браузерах различаются, но суть одна:
- Chrome и Edge: «Ошибка 502 Bad Gateway».
- Firefox: «502 Bad Gateway».
- Часто у nginx — собственная страница: «502 Bad Gateway» и строка
nginx/1.x.xвнизу.

Почему возникает 502: типичные причины
Причины почти всегда связаны с тем, что бэкенд за прокси либо не запущен, либо не отвечает, либо отвечает неправильно. Разберём по классам.
Бэкенд-процесс не работает
Самая частая причина: PHP-FPM, Node.js или другой обработчик упал, аварийно завершился или не стартовал после перезагрузки сервера. Прокси жив, но ему некому передать запрос — отсюда 502.
Бэкенд слушает не тот порт или сокет
Прокси настроен на один порт или unix-сокет, а приложение слушает другой. Типичный случай после обновления конфигурации: nginx ждёт PHP-FPM на 127.0.0.1:9000, а тот переключился на сокет /run/php/php8.2-fpm.sock.
Таймаут ответа
Бэкенд работает, но отвечает слишком медленно, а у прокси истёк лимит ожидания. Такое бывает при тяжёлых запросах, перегрузке приложения или медленной базе данных.
Бэкенд отвечает мусором
Приложение упало на середине генерации ответа и отдало повреждённые данные, которые прокси не смог разобрать — результат тот же 502.
Таблица причин
| Симптом / признак | Вероятная причина | Решение |
|---|---|---|
| 502 на всех страницах сразу | Бэкенд упал или не запущен | Перезапустить PHP-FPM/приложение, проверить статус службы |
| 502 после перезагрузки сервера | Служба не стартует автоматически | Включить службу в автозагрузку, проверить логи запуска |
| 502 после правки конфигурации nginx | Неверный порт/сокет upstream | Сверить fastcgi_pass/proxy_pass с реальным адресом бэкенда |
| 502 только на тяжёлых страницах | Таймаут прокси, медленный бэкенд | Поднять fastcgi_read_timeout, оптимизировать запросы |
502 с upstream prematurely closed в логе |
Бэкенд оборвал соединение | Проверить лог бэкенда, увеличить request_terminate_timeout |
502 с connect() failed (111: Connection refused) |
На порту/сокете никто не слушает | Запустить бэкенд, исправить адрес в конфигурации |
| 502 периодически, то есть, то нет | Перегрузка, нехватка воркеров | Увеличить число воркеров, разобраться с нагрузкой |
502 с upstream sent too big header |
Заголовок ответа превысил лимит | Поднять буферы fastcgi_buffer_size и fastcgi_buffers |
Как диагностировать 502: логи nginx
Лог nginx — первое место, куда нужно смотреть. Запись об ошибке практически всегда говорит, что именно пошло не так.
Типичные записи и их расшифровка
tail -n 50 /var/log/nginx/error.log
Разберём самые частые сообщения.
1. Connection refused:
connect() failed (111: Connection refused) while connecting to upstream
Расшифровка: nginx попытался соединиться с бэкендом по указанному адресу и порту, но там никто не слушает. Значит, либо PHP-FPM/приложение не запущено, либо адрес в конфигурации указан неверно.
2. Преждевременное закрытие соединения:
upstream prematurely closed connection while reading response header from upstream
Расшифровка: соединение установилось, но бэкенд закрыл его, не успев отдать заголовки ответа. Обычно это означает, что приложение упало в процессе обработки запроса — например, фатальная ошибка PHP, которую нужно искать в логах самого PHP-FPM.
3. Таймаут:
upstream timed out (110: Connection timed out) while reading response header from upstream
Расшифровка: nginx ждал ответа дольше установленного лимита. Причина — медленный бэкенд или слишком маленькое значение таймаута.
4. Слишком большой заголовок:
upstream sent too big header while reading response header from upstream
Расшифровка: ответ бэкенда содержит слишком много данных в заголовках (часто из-за множества cookies или крупного заголовка). Лечится увеличением буферов.
Проверяем бэкенд напрямую
Полезно выяснить, жив ли бэкенд сам по себе, в обход прокси. Если он слушает на TCP-порту, проверить можно так:
curl -v http://127.0.0.1:9000/ 2>&1 | head -n 20
Если PHP-FPM работает, вы увидите ответ, начинающийся с попытки установить соединение. Если порт закрыт, curl вернёт Connection refused — значит, бэкенд не запущен или слушает другой порт.
Для unix-сокета проверка выполняется иначе. Сначала убедимся, что сокет существует:
ls -la /run/php/php8.2-fpm.sock
Затем проверим, кто его слушает:
ss -xl | grep php-fpm
Если сокета нет в списке, PHP-FPM не работает — его нужно перезапустить.
Проверяем статус службы PHP-FPM
systemctl status php8.2-fpm
Вывод покажет состояние службы. Строка active (running) — служба работает. Строка failed или inactive означает, что процесс упал или не запущен. В этом случае:
systemctl restart php8.2-fpm
После перезапуска снова проверьте статус — служба должна стать active (running).

Логи самого бэкенда
Если nginx показывает 502, а сам он исправен, копаем глубже — в логи приложения. Для PHP-FPM это обычно /var/log/php8.2-fpm.log:
tail -n 50 /var/log/php8.2-fpm.log
Там можно увидеть фатальные ошибки скриптов, исчерпание лимитов памяти или нехватку воркеров. Именно эти записи укажут на реальную причину, по которой бэкенд падает или не отвечает.
Конфигурация nginx: частые ошибки
Половина проблем с 502 решается исправлением конфигурации. Рассмотрим типичные места.
Несовпадение адреса в fastcgi_pass
Секция, отвечающая за передачу запроса PHP-FPM, выглядит примерно так:
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
Ключевая строка — fastcgi_pass. Её значение должно точно совпадать с тем, как реально запущен PHP-FPM. Если в конфигурации PHP-FPM указан listen = 127.0.0.1:9000, а в nginx — unix:/run/php/php8.2-fpm.sock, запросы будут получать 502. Проверьте директиву listen в /etc/php/8.2/fpm/pool.d/www.conf и приведите адреса в соответствие.
Таймауты
Если 502 возникает только на долгих операциях, поднимите лимиты ожидания:
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
Значения в секундах. 300 даёт бэкенду пять минут на ответ — этого хватает для большинства тяжёлых операций. Но если запрос стабильно требует больше, лучше разобраться, почему он такой медленный, а не задирать таймауты бесконечно.
Буферы заголовков
Для ошибки upstream sent too big header увеличьте буферы:
fastcgi_buffer_size 16k;
fastcgi_buffers 16 16k;
fastcgi_buffer_size задаёт размер буфера для чтения заголовка ответа, fastcgi_buffers — число и размер буферов для тела ответа. Значения 16k покрывают большинство случаев.
Другие бэкенды: Node.js, Python и проксирование
502 возникает не только в связке nginx + PHP-FPM. Любой reverse proxy перед приложением способен отдать эту ошибку, если приложение не отвечает.
Проксирование HTTP-приложения через proxy_pass
Когда за nginx стоит самостоятельный HTTP-сервер (Node.js на Express, Python на Gunicorn/uWSGI, Go-приложение), используется директива proxy_pass:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
}
Здесь nginx передаёт запросы приложению, которое слушает порт 3000. Если приложение упало или не стартовало, nginx вернёт 502 — по той же причине «там никто не слушает». Проверить порт можно так:
ss -tlnp | grep 3000
Если порт 3000 не появляется в выводе, приложение не запущено. Запустите его и убедитесь, что адрес в proxy_pass совпадает с тем, где реально слушает приложение.
Проверка HTTPS-бэкенда через openssl
Если за прокси стоит бэкенд, отвечающий по HTTPS, проверить его рукопожатие и сертификат можно напрямую командой openssl, минуя прокси:
openssl s_client -connect 127.0.0.1:443 -servername example.com </dev/null 2>/dev/null | head -n 5
Разбор: s_client устанавливает TLS-соединение с бэкендом, -connect 127.0.0.1:443 — адрес и порт, -servername example.com — имя для SNI, </dev/null закрывает stdin, чтобы команда завершилась сразу после рукопожатия. Если вывод начинается со строки CONNECTED и следом идут данные сертификата — бэкенд отвечает по HTTPS. Если соединение не установилось, проблема на стороне бэкенда, и прокси закономерно отдаёт 502.
Типичный сценарий: приложение под systemd упало
Для приложений, работающих как служба systemd, алгоритм тот же, что и для PHP-FPM. Посмотрите статус и логи:
systemctl status myapp
journalctl -u myapp -n 50
systemctl status myapp покажет, работает ли служба, а journalctl -u myapp -n 50 выведет последние 50 строк её журнала — там будет причина падения (необработанное исключение, ошибка конфигурации, нехватка памяти). Устранив причину и перезапустив службу, вы уберёте и 502.
Связка с другими проблемами: 502 и сертификаты
Иногда 502 появляется в связках, где первопричина не очевидна. Например, при обращении через HTTPS на сайт с проблемным сертификатом часть запросов может не доходить до бэкенда — хотя чаще всего в таких случаях браузер покажет ошибку сертификата, а не 502.
Если вы видите 502 только при обращении по HTTPS, а по HTTP сайт работает, проверьте цепочку: сертификат, его срок действия и корректность настройки SSL на прокси. Проверить сертификат можно отдельно — например, инструментом проверки SSL, который покажет, корректен ли сертификат и не истёк ли он. Просроченный или неверно установленный сертификат на прокси-слое тоже способен ломать передачу запросов к бэкенду.
Профилактика: чтобы 502 не повторялась
- Включите автозагрузку бэкенда. Убедитесь, что PHP-FPM и приложение стартуют после перезагрузки:
systemctl enable php8.2-fpm. Это устраняет самый частый сценарий «перезагрузили сервер — получили 502». - Сверяйте конфигурацию при изменениях. После любой правки
nginx.confили пула PHP-FPM проверяйте, чтоfastcgi_pass/proxy_passиlistenсовпадают. - Следите за ресурсами. Нехватка памяти или воркеров — частая причина периодических 502. Настройте алерты о превышении порогов.
- Держите логи под рукой. Разбирайте
error.lognginx и логи бэкенда регулярно — многие проблемы дают о себе знать предупреждениями до того, как стать 502. - Проверяйте сайт снаружи после релиза. Внутренние проверки не всегда видят то, что видит пользователь. Прогоняйте ключевые страницы через инструмент проверки доступности после каждого развёртывания, чтобы убедиться, что сайт отдаёт 200, а не 502.
Как и в случае с ошибкой 500, внутренний мониторинг инфраструктуры (например, Zabbix) дополняет внешнюю проверку: он следит за здоровьем серверов и служб изнутри и сигнализирует о том, что PHP-FPM упал или перегружен, ещё до того, как это превратится в 502 для посетителей. Внешний же мониторинг отвечает на вопрос, что реально видит пользователь, открывая сайт из интернета.
Соседние ошибки 5xx
- Ошибка 504 Gateway Timeout — похожа на 502, но причина строго в том, что бэкенд не уложился в отведённое время. Если вместо 502 вы видите 504, дело почти наверняка в таймаутах и медленном бэкенде, а не в том, что он упал.
Коротко
Ошибка 502 Bad Gateway означает, что прокси-сервер не смог получить корректный ответ от бэкенда. Причина почти всегда на стыке двух серверов: бэкенд упал, слушает не тот порт, не уложился в таймаут или ответил повреждёнными данными.
Диагностика строится на логах nginx — записи Connection refused, upstream prematurely closed и upstream timed out прямо указывают на характер проблемы. Дальше проверяем сам бэкенд: статус службы systemctl status php8.2-fpm, наличие unix-сокета, прямые запросы через curl. После исправления сверяем конфигурацию и проверяем сайт снаружи — инструмент проверки доступности UptimeChecker покажет, какой код статуса сервер отдаёт реальным посетителям.