Skip to content
← Все статьи

502 Bad Gateway: что значит и как починить

Ошибка 502 Bad Gateway означает, что прокси-сервер (nginx, Apache, Cloudflare) не получил валидный ответ от upstream-сервера (PHP-FPM, Node.js, uwsgi, Gunicorn). Это не проблема прикладного кода, а сбой между прокси и backend'ом.

В статье разберём, что конкретно означает 502 в разных stack'ах, 7 частых причин и пошаговые решения для nginx + PHP-FPM, Node.js и Apache, с примерами конфигов.

Что означает 502

По RFC 9110 §15.6.3, 502 указывает, что сервер, действуя как gateway или proxy, получил некорректный ответ от upstream. В отличие от 504 (timeout), 502 — это синтаксический или соединительный провал: upstream упал, вернул мусор или reset соединения.

Архитектура запроса и где возникает 502

Browser → CDN/Cloudflare → nginx → PHP-FPM / Node.js / uwsgi
                            ↑
                            502 от этого звена, если upstream:
                            - не отвечает
                            - вернул невалидный HTTP
                            - закрыл соединение
                            - timeout при connect()

7 частых причин 502

  1. PHP-FPM / Node.js упал или не запущен.
  2. Worker пул исчерпан — все children заняты.
  3. OOM Killer убил процесс — система исчерпала RAM.
  4. Upstream timeout при connect().
  5. Сломанный socket (unix socket удалён или без прав).
  6. Deploy в процессе — upstream перезапускается.
  7. Слишком большие заголовки — buffer переполнен.

Диагностика 502

Проверьте внешне через HTTP Header Checker от Enterno.io, затем копайте серверные логи.

# Статус процессов
systemctl status php8.4-fpm
systemctl status nginx
pm2 list  # для Node.js

# Логи
tail -100 /var/log/nginx/error.log
tail -100 /var/log/php8.4-fpm.log

# Проверьте OOM Killer
dmesg | grep -i "killed process\|out of memory"
journalctl --since "10 minutes ago" | grep -i oom

# Проверьте socket
ls -la /var/run/php/php8.4-fpm.sock
# Должно быть: srw-rw---- 1 www-data www-data

Решения

1. Перезапустить upstream

systemctl restart php8.4-fpm
systemctl restart nginx
# или PM2
pm2 restart all

2. Увеличить worker пул PHP-FPM

# /etc/php/8.4/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500

# Для высокой нагрузки:
pm = static
pm.max_children = 100
pm.max_requests = 1000

systemctl reload php8.4-fpm

Правильный размер пула: max_children = (RAM - 500MB) / avg_worker_MB. Мониторьте через pm.status_path = /fpm-status.

3. Увеличить buffer и timeout в nginx

http {
    # Увеличьте если upstream отправляет большие заголовки
    fastcgi_buffer_size 128k;
    fastcgi_buffers 8 128k;
    fastcgi_busy_buffers_size 256k;

    # Увеличьте timeout для медленных upstream
    fastcgi_connect_timeout 30s;
    fastcgi_send_timeout 60s;
    fastcgi_read_timeout 60s;

    # Для проксирования к Node.js
    proxy_buffer_size 128k;
    proxy_buffers 8 128k;
    proxy_busy_buffers_size 256k;
    proxy_connect_timeout 30s;
    proxy_read_timeout 60s;
}

4. Проверить и починить socket

# Если используете unix socket
listen = /var/run/php/php8.4-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

# Альтернатива — TCP (меньше проблем с правами):
listen = 127.0.0.1:9000

5. Защита от OOM

# Увеличьте memory_limit в PHP осторожно
memory_limit = 256M

# swap файл (для VPS с малой RAM)
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile none swap sw 0 0" >> /etc/fstab

# Приоритет OOM для критичных процессов
systemctl edit php8.4-fpm
# [Service]
# OOMScoreAdjust=-500

6. Graceful deploy с zero-downtime

# Blue-green через nginx
upstream backend {
    server 127.0.0.1:3000;  # blue
    server 127.0.0.1:3001 backup;  # green
}

# Reload вместо restart
systemctl reload php8.4-fpm  # без downtime
pm2 reload all  # zero-downtime restart

7. Node.js специфика

// Unhandled rejection = процесс упадёт = 502
process.on('unhandledRejection', (reason) => {
  logger.error('Unhandled Rejection:', reason);
  // Не вылетаем — продолжаем работать
});

process.on('uncaughtException', (err) => {
  logger.error('Uncaught Exception:', err);
  // Стратегия: логируем и продолжаем (или graceful shutdown)
});

// PM2 для автоматического restart
// pm2 start app.js --max-memory-restart 500M

502 от Cloudflare — что делать

Если Cloudflare показывает 502 с ID cf-ray:

  1. Проверьте, что origin отвечает напрямую (обойдите CF через curl -H 'Host: example.com' http://ORIGIN_IP).
  2. Проверьте проверку SSL на origin — истёкший = 502 от CF.
  3. Уточните, что origin не блокирует CF IP ranges (WAF, firewall).
  4. Проверьте CF Workers — ошибка в коде worker возвращает 502.

Мониторинг и предотвращение

Настройте Enterno.io Monitors с expected_code=200 и регионами ru-msk + eu-de — вы сразу узнаете о 502, даже если он виден только из определённой географии. Подключите Telegram или Slack для мгновенных алертов.

Часто задаваемые вопросы (FAQ)

В: Чем отличается 502 от 504?
О: 502 — upstream вернул мусор или закрыл connection. 504 — upstream не ответил за отведённое время.

В: Почему после deploy возникает 502?
О: Upstream перезапускается. Решение: graceful reload вместо restart + zero-downtime deploy через PM2/systemd.

В: 502 только иногда — что проверять?
О: Worker пул, OOM Killer, timeout на медленных запросах, состояние socket'а.

Заключение

502 — проблема между прокси и backend'ом. Всегда начинайте с проверки статуса upstream процессов, затем логов. Правильно настройте пул worker'ов, buffer'ы, timeout'ы и защиту от OOM. мониторинг сайтов через Enterno.io поймает регрессии мгновенно.

Проверьте ваш сайт прямо сейчас

Проверить →
Другие статьи: HTTP
HTTP
301 vs 302 редирект: разница и когда что использовать
15.04.2026 · 5 просм.
HTTP
HTTP коды ответов: полный справочник с примерами
10.03.2025 · 65 просм.
HTTP
HTTP/2 vs HTTP/3: что нового и зачем переходить
14.03.2026 · 35 просм.
HTTP
HTTP кэширование: Cache-Control, ETag, Expires
14.03.2026 · 36 просм.