Выберите продукт

HTTP 4xx и 5xx: как диагностировать и чинить ошибки на Nginx и Apache

Практическое руководство для админов и девопсов по диагностике и устранению HTTP ошибок 4xx и 5xx: от 500 до 502, 503 и 504. Разберём коды статусов, кто их отдаёт в связке Nginx, Apache и backend, где смотреть логи и какие настройки веб‑сервера и PHP‑FPM проверить в первую очередь.
HTTP 4xx и 5xx: как диагностировать и чинить ошибки на Nginx и Apache

HTTP‑коды 4xx и 5xx — это тот случай, когда пользователи видят только «на сайте что-то не так», а админ должен за пару минут понять, где именно всё сломалось. В этой статье разберём, как системно подходить к диагностике и починке популярных ошибок: http 500, http 502, http 504 и других статус‑кодов на связке Nginx/Apache и PHP‑приложениях.

Быстрый чек‑лист: с чего начать при любой 4xx/5xx

Когда «горит прод», важно не метаться между конфигами, а пройтись по простому алгоритму.

  1. Уточнить код ошибки: что именно видит пользователь — 404, 403, 500, 502, 503, 504?
  2. Проверить, кто отдаёт ошибку: Nginx, Apache или само приложение (PHP, Node.js, Django и т.д.).
  3. Сразу открыть логи:
    • для Nginx: access_log и error_log;
    • для Apache: access.log и error.log виртуального хоста;
    • логи backend‑процесса: PHP‑FPM, uwsgi, gunicorn, само приложение.
  4. Воспроизвести проблему сами с curl/браузера, желательно с тем же URL и параметрами.
  5. Определить слой проблемы: DNS, балансировщик, reverse‑proxy, веб‑сервер, backend, база, внешние API.

Базовое правило: любая 5xx почти всегда означает «сломался сервер или backend», любая 4xx — «клиентский запрос некорректен или запрещён», но часть 4xx сознательно генерирует ваше приложение в ответ на ошибки логики или авторизации.

Разбор популярных 5xx: 500, 502, 503, 504

Начнём с наиболее болезненной для продакшена группы — 5xx. Они напрямую говорят, что на сервере что-то не так, и это уже ваша зона ответственности.

HTTP 500 Internal Server Error

http 500 — универсальный код «у нас что-то сломалось». Чаще всего источник:

  • PHP‑приложение (фатальная ошибка, необработанное исключение);
  • Apache с модулем mod_php или mod_proxy_fcgi (ошибка в .htaccess или конфиге виртуального хоста);
  • CGI/FastCGI‑скрипты или другие backend‑обработчики.

Классический кейс для PHP‑проекта под Apache — ошибка в .htaccess. В этом случае 500 вернёт сам Apache, а в error.log вы увидите нечто вроде «Invalid command» или «RewriteRule: bad flag». Для Nginx + PHP‑FPM типичная причина — краш воркера PHP‑FPM или фатальная ошибка, из-за которой код не доходит до отдачи ответа.

Как диагностировать 500

  1. Сделать запрос с curl и посмотреть заголовки:
curl -i example.com/problem/url

По заголовку Server и формату страницы ошибки можно понять, кто именно её отдаёт (Nginx, Apache, приложение или балансировщик).

  1. Проверить error‑логи веб‑сервера за последние минуты.

Примеры путей:

  • Nginx: /var/log/nginx/error.log или отдельный лог виртуального хоста;
  • Apache: /var/log/apache2/error.log или /var/log/httpd/error_log.
  1. Проверить логи backend‑приложения.

Для PHP‑FPM, например:

tail -n 100 /var/log/php8.2-fpm.log

Если используется фреймворк (Laravel, Symfony и т.п.), смотрим его собственные логи: там часто будет полноценный stack trace конкретной ошибки.

Типичные причины 500 и как чинить

  • Ошибки в .htaccess (Apache): неправильные директивы, синтаксические ошибки. Проверяем логи, временно комментируем подозрительные строки или отключаем .htaccess, перенося правила в конфиг vhost.
  • Фатальные ошибки PHP: Allowed memory size exhausted, Call to undefined function и подобное. Лечится увеличением лимита памяти, установкой недостающих расширений, исправлением кода.
  • Отсутствующие файлы/классы после деплоя: не загружены vendor‑библиотеки, миграции не прогнаны, неверные пути в автозагрузке.
  • Неправильные права на файлы/директории: PHP не может читать конфиг/кэш, писать в storage и лог‑директории.

HTTP 502 Bad Gateway

http 502 в контексте Nginx/Apache почти всегда значит: reverse‑proxy не смог корректно получить или распарсить ответ от backend‑сервера.

Типичный сценарий: фронтовый Nginx проксирует запросы на PHP‑FPM, Apache, Node.js или другой upstream. Если backend падает, не отвечает, отдаёт битый заголовок или неожиданно закрывает соединение, Nginx вернёт 502.

Где искать причину 502

  • Логи Nginx: ищем по статусу 502 в access_log и по сообщениям upstream prematurely closed connection, bad gateway в error_log.
  • Логи backend: PHP‑FPM, Apache (на backend‑роли), само приложение.
  • Жив ли backend‑порт: проверяем ss или netstat и curl к самому upstream.

Пример curl к HTTP‑backend (Node.js, второй Nginx/Apache):

curl -i 127.0.0.1:8080/health

Причины 502 на связке Nginx + PHP‑FPM

  • Нет доступных воркеров PHP‑FPM: все заняты долгими запросами, пул достиг pm.max_children, новые соединения отклоняются.
  • PHP‑FPM упал или не запущен: Nginx пытается подключиться к сокету или порту, которого нет.
  • Неверные настройки fastcgi: неправильный fastcgi_pass, ошибка в пути до сокета, права на сокет.
  • Сломанный backend‑ответ: баг в приложении, который приводит к тому, что HTTP‑заголовки отдаются некорректно или в неверной последовательности.

В error.log Nginx вы часто увидите что-то вроде:

connect() to unix:/run/php/php8.2-fpm.sock failed (2: No such file or directory) while connecting to upstream

или:

upstream prematurely closed connection while reading response header from upstream

В первом случае всё очевидно — PHP‑FPM не запущен или сокет в другом месте. Во втором — PHP‑код завершил работу с крэшем до того, как отправил заголовки.

HTTP 503 Service Unavailable

503 используется как для планового обслуживания, так и в случае перегрузки/недоступности сервера. Часто 503 формирует сам backend‑сервер (например, Apache или приложение), но вы можете настроить Nginx отдавать 503, если все upstream‑серверы признаны недоступными.

Типичные причины:

  • вы сами включили maintenance‑режим (фреймворк или кастомная страница обслуживания);
  • идёт перезапуск backend‑сервиса (PHP‑FPM, Apache, Node.js), часть запросов попадает «в окно» недоступности;
  • ограничения по числу процессов/соединений, из‑за чего новые запросы отклоняются;
  • backend вернул 503 при перегрузке (очереди задач, база «захлебнулась» и т.п.).

В логах Nginx/Apache ищем строки с 503 и сопоставляем по времени с перезапусками сервисов и метриками нагрузки (CPU, RAM, диски, база данных).

HTTP 504 Gateway Timeout

http 504 говорит, что reverse‑proxy (чаще всего Nginx) не дождался ответа от upstream за отведённое время. Это не просто «завис веб», а конкретный таймаут.

Где настраивается таймаут в Nginx

За http 504 обычно отвечает параметр proxy_read_timeout (для HTTP‑upstream) или fastcgi_read_timeout (для PHP‑FPM). Если backend выполняет запрос слишком долго (большой отчёт, тяжёлая SQL‑операция, внешнее API тормозит), Nginx обрывает соединение и отдаёт клиенту 504.

Пример фрагмента конфига Nginx:

location / {
    proxy_pass http://backend;
    proxy_read_timeout 60s;
}

Если backend регулярно укладывается в 30 секунд, но иногда прыгает до 90 — вы будете получать периодические 504.

Типичные причины 504

  • Медленные SQL‑запросы: отсутствие индексов, сложные JOIN, блокировки в базе.
  • Внешние API: ваши запросы ждут ответа третьей стороны, которая тормозит или падает.
  • Перегрузка backend‑сервера: CPU 100%, диск в I/O wait, очередь запросов растёт.
  • Слишком агрессивные таймауты в Nginx или Apache как reverse‑proxy.

Подход к лечению:

  1. Найти самые долгие запросы в логах приложения или в slow query log СУБД.
  2. Оптимизировать запросы, добавить индексы, вынести тяжёлые задачи в очередь.
  3. При необходимости аккуратно увеличить proxy_read_timeout или fastcgi_read_timeout, но не заменять архитектурные проблемы бесконечным таймаутом.

Частые 4xx: 400, 401, 403, 404, 405, 429

Ошибки 4xx формально означают «проблема на стороне клиента», но на практике их часто создаёт серверная логика. Ниже — разбор по популярным кодам и местам, где их диагностировать.

HTTP 400 Bad Request

400 обычно означает, что сервер не смог понять запрос. В Nginx это может быть слишком большой заголовок, битый HTTP‑формат, невалидный Host и т.п.

В контексте Nginx типовые причины:

  • слишком большой cookie (превышен large_client_header_buffers);
  • битый запрос от клиента/прокси;
  • неверный Host, который блокируется по безопасности.

В error.log это будет выглядеть как:

client sent too large header while reading client request headers

Решение — увеличить буферы или уменьшить размер cookie (часто помогает чистка куков в браузере, но на уровне сервера лучше не раздувать значение без необходимости).

HTTP 401 Unauthorized и 403 Forbidden

401 — требует авторизации (обычно Basic/Digest/JWT и т.п.). 403 — доступ запрещён даже при наличии авторизации (или она неверная по бизнес‑логике).

На уровне Nginx/Apache 401/403 часто связаны с конфигурацией:

  • неправильные права на файлы/директории (веб‑сервер физически не может их читать);
  • ограничения по IP (allow/deny в Nginx, Require ip в Apache);
  • блокировка каталога листинга (Options -Indexes в Apache, autoindex off в Nginx).

В бизнес‑логике приложения 403 часто означает «недостаточно прав», «заблокированный аккаунт» и т.п., и генерируется кодом.

HTTP 404 Not Found

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

На уровне веб‑сервера 404 означает, что путь не сопоставился ни с одним location/Alias и файл не найден. В связке с PHP‑фреймворками это чаще значит, что маршрутизация приложения не нашла нужный роут.

Порядок проверки:

  1. Посмотреть логи веб‑сервера: виден ли запрос, правильный ли server_name, не попали ли вы в «дефолтный» vhost.
  2. Для Apache — не сломался ли mod_rewrite или правило в .htaccess.
  3. Для Nginx — корректен ли try_files, не забыто ли index в location /.
  4. Проверить логи приложения: дошёл ли запрос до фреймворка.

Если вы активно используете кеширование, имеет смысл посмотреть и на заголовки кеш‑управления. Про работу с кешем статических файлов и HTTP‑заголовками подробнее написано в материале о настройке Cache-Control и ETag в Nginx и Apache.

HTTP 405 Method Not Allowed

405 сообщает, что к ресурсу нельзя обращаться указанным методом (например, POST к URL, который принимает только GET).

Часто это результат конфигурации роутинга в приложении, но может быть и эффектом Nginx/Apache, если вы явно ограничивали методы, например через limit_except в Nginx или <LimitExcept> в Apache.

HTTP 429 Too Many Requests

429 обычно генерируют защита от DDoS/брутфорса или rate‑limit — в Nginx это limit_req, в Apache — модули типа mod_ratelimit или внешние решения.

Если пользователи жалуются на 429, а вы уверены, что трафик легитимный, проверьте правила rate‑limit: возможно, слишком жёсткий лимит или неправильная ключевая метка (например, ограничиваете по IP вместо API‑ключа, user id или токена авторизации).

Иногда вместе с 4xx/5xx встают вопросы к заголовкам безопасности, CORS и прочим политикам. Для более тонкой настройки заголовков можно ориентироваться на разбор в статье о HTTP заголовках безопасности для Nginx и Apache.

Панель мониторинга с графиками по HTTP кодам и доле ошибок 5xx

Nginx: где искать причину и что крутить

Для ошибок http 500, http 502, http 504 в связке с Nginx важно понимать, какие параметры могут спровоцировать или, наоборот, смягчить ситуацию. Особенно это критично, если у вас много сайтов на одном сервере или на тарифах виртуального хостинга, и ошибка на одном проекте может аффектить общую нагрузку.

Ключевые параметры Nginx, влияющие на 4xx/5xx

  • client_max_body_size — максимальный размер тела запроса. Превышение приводит к 413 (Payload Too Large), но пользователи часто воспринимают это как «ошибку сервера».
  • client_body_timeout — сколько Nginx ждёт, пока клиент отправит тело запроса.
  • client_header_timeout и large_client_header_buffers — влияют на 400 при больших куках и заголовках.
  • proxy_connect_timeout, proxy_read_timeout, proxy_send_timeout — главные подозреваемые при 502/504 с HTTP‑upstream.
  • fastcgi_connect_timeout, fastcgi_read_timeout, fastcgi_send_timeout — аналогично для PHP‑FPM и других FastCGI.
  • proxy_next_upstream, proxy_next_upstream_timeout — задают, как Nginx ведёт себя при ошибках upstream‑серверов (повторяет ли запросы, на какие коды переключается и т.д.).

При отладке проблем внимательно смотрим на связку:

  • что показывает error_log Nginx в момент ошибки;
  • что показывает лог upstream‑приложения в то же время;
  • нет ли корреляции с пиками нагрузки по метрикам (CPU, RAM, disk IO, база).

Apache: типичные источники 500/503

В случае Apache своя специфика: обилие модулей, поддержка .htaccess, разные режимы работы PHP (mod_php, php-fpm, proxy_fcgi). Ошибка конфигурации легко превращается в массовые 500/503.

.htaccess как источник http 500

Ошибки в .htaccess — классический случай для http 500:

  • опечатка в директиве;
  • использование модулей, которые не загружены (например, правила Rewrite без включённого mod_rewrite);
  • некорректные условия в RewriteCond или регулярные выражения.

При этом Apache часто пишет понятные сообщения в error.log, по которым можно сразу понять, где именно проблема. Если 500 появляется сразу после попадания файла/строки в .htaccess — почти наверняка виноват он.

mod_proxy_fcgi и проксирование к PHP‑FPM

Если Apache выступает как фронтовый сервер и проксирует запросы к PHP‑FPM, многие симптомы схожи с Nginx:

  • если PHP‑FPM не встаёт — будут 502/503;
  • если PHP‑FPM перегружен — возможны таймауты и 504;
  • если неправильно указан сокет/порт — сразу 502/500.

Логи Apache в этом случае будут содержать ошибки вида «proxy: error reading status line from remote server», которые напрямую укажут на проблемы соединения с backend.

Администратор сверяет конфигурации Apache и Nginx для поиска причин ошибок 5xx

Практический сценарий: «Сайт начал отдавать 502/504»

Разберём типичный инцидент на связке nginx + php-fpm.

Симптом: пользователи жалуются, что сайт периодически отдаёт http 502 и http 504. Нагрузку сильно не повышали, обновлений не разворачивали. Что делать?

Шаг 1. Фиксируем время и URL

Просим пользователя или берём из мониторинга точное время ошибки и URL. Сами воспроизводим проблему curl‑ом или браузером, желательно с теми же параметрами и заголовками.

Шаг 2. Смотрим логи Nginx

Ищем строки с 502/504 за указанный период:

grep " 502 " /var/log/nginx/access.log | tail -n 20
grep " 504 " /var/log/nginx/access.log | tail -n 20

В error.log ищем сообщения с upstream:

grep upstream /var/log/nginx/error.log | tail -n 50

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

Шаг 3. Проверяем состояние PHP‑FPM

  • жив ли сервис: systemctl status php8.2-fpm;
  • есть ли ошибки в логах PHP‑FPM: фатальные ошибки, «server reached max children» и т.п.;
  • не достигнут ли лимит pm.max_children и нет ли сообщений о нехватке процессов.

Если видим «server reached pm.max_children» или постоянные сообщения о занятости воркеров — причина в перегрузке пула.

Шаг 4. Анализируем нагрузку и долгие запросы

Параллельно смотрим:

  • графики CPU, RAM, IO;
  • медленные SQL‑логи (slow query log в MySQL/PostgreSQL);
  • логи самого приложения на предмет долгих операций (отчёты, генерация файлов, запросы к внешним API).

Нередко выясняется, что один‑два тяжёлых отчёта или API‑эндпоинта держат по несколько минут CPU и блокируют воркеры PHP‑FPM. Отсюда — 502/504 для остальных пользователей.

Шаг 5. Временное смягчение и долгосрочное решение

Временные меры:

  • аккуратно увеличить fastcgi_read_timeout в Nginx для проблемного location;
  • увеличить pm.max_children в PHP‑FPM, если хватает памяти;
  • ограничить одновременные тяжёлые запросы (на уровне приложения или WAF).

Долгосрочные:

  • оптимизировать медленные SQL‑запросы и кэшировать тяжёлые страницы;
  • вынести длительные операции в фоновые задачи (очереди);
  • разделить пулы PHP‑FPM под разные типы трафика (API, админка, фронт) с разными лимитами.

Практический сценарий: «После правки .htaccess стал http 500»

Второй частый случай — Apache и .htaccess. Ошибка в одном файле легко валит весь сайт.

Шаг 1. Возвращаем предыдущую версию

Если есть резервная копия .htaccess до правки — откатываем её. Если нет — временно комментируем новые правила, чтобы восстановить работоспособность сайта и уменьшить время простоя.

Шаг 2. Ищем точную ошибку в error.log

Открываем error.log виртуального хоста и смотрим последние записи после запроса:

  • сообщения «Invalid command», «RewriteRule: bad flag» и подобные ссылаются на конкретную строку;
  • часто указывается даже номер строки, что сильно упрощает поиск.

Шаг 3. Проверяем наличие нужных модулей

Если вы пользуетесь директивами из mod_rewrite, mod_expires, mod_headers и др., убедитесь, что они загружены в основном конфиге Apache. Иначе даже корректное правило в .htaccess приведёт к 500.

Организация логов и мониторинга по HTTP‑кодам

Чтобы не искать 500/502/504 вручную в логах, полезно заранее организовать:

  • парсинг access‑логов Nginx/Apache (GoAccess, ELK/EFK, Loki, Prometheus‑экспортеры);
  • алерты по росту доли 5xx в минуту/час;
  • разделение логов по сервисам и vhost‑ам, чтобы быстрее локализовать проблему.

Минимум, который можно сделать даже без сложной инфраструктуры — периодически проверять статистику кодов статус‑ответов, например с помощью GoAccess, и включить мониторинг готовности сайта с простыми HTTP‑проверками (поиском 200/3xx/4xx/5xx по ключевым URL).

Итоги

Ошибки HTTP 4xx и 5xx — нормальная часть жизни любого боевого проекта. Они становятся проблемой только тогда, когда нет понятного алгоритма действий. Для http 500, http 502, http 504 и других статус‑кодов базовый подход всегда один и тот же:

  • зафиксировать точный код и время;
  • понять, кто именно отдаёт ошибку: Nginx, Apache, балансировщик или само приложение;
  • сопоставить сообщения в логах веб‑сервера и backend‑сервисов;
  • проверить настройки таймаутов, лимитов и параметры пулов (PHP‑FPM и др.);
  • посмотреть на нагрузку и долгие операции (SQL, внешние API, фоновые задачи).

Если вы будете каждый инцидент разбирать именно в такой последовательности, через пару недель 500/502/504 перестанут быть «магией» и станут обычными задачами по диагностике инфраструктуры и оптимизации кода. А при грамотной организации логов и мониторинга вы будете успевать заметить всплеск 5xx ещё до того, как пользователи напишут, что «сайт снова не работает».

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND

Если локальный DNS в Debian или Ubuntu не стартует с ошибкой address already in use, причина часто в systemd-resolved и DNSStubLis ...
Debian/Ubuntu: как исправить NFS mount.nfs: access denied by server while mounting OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить NFS mount.nfs: access denied by server while mounting

Ошибка mount.nfs: access denied by server while mounting в Debian и Ubuntu обычно указывает на проблему на стороне NFS-сервера: не ...
Debian/Ubuntu: как устранить конфликт systemd-resolved DNSStubListener с BIND9, dnsmasq и AdGuard Home OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как устранить конфликт systemd-resolved DNSStubListener с BIND9, dnsmasq и AdGuard Home

Если в Debian или Ubuntu DNS-сервер не стартует из-за ошибки port 53 busy, часто причина в systemd-resolved с локальным слушателем ...