Ошибка 503 Service Unavailable: причины и решение
Что такое ошибка 503
Код ответа 503 Service Unavailable означает, что сервер получил ваш запрос, понял его, но в данный момент не может его обработать. Это не ошибка в самом запросе (как 404 или 400) и не поломка в логике приложения (как 500). Сайт «жив», но временно отключён или перегружен, и сервер честно сообщает об этом.
Ключевое слово здесь — «временно». В отличие от 500 Internal Server Error, которую нужно чинить в коде, 503 почти всегда возникает из-за внешних по отношению к приложению условий: сервер перегружен, на нём идут технические работы, исчерпан лимит одновременных соединений или сломался один из промежуточных сервисов.
Формально 503 входит в семейство ответов 5xx — «ошибка сервера». Но это единственный код из этого семейства, который по стандарту HTTP (RFC 7231) не означает, что что-то сломано: он просто сообщает, что сервер сейчас не готов обслуживать запросы. Именно поэтому в ответе 503 часто приходит заголовок Retry-After, который подсказывает клиенту, через сколько секунд стоит попробовать снова.

Почему это важно понимать: если вы видите 503 на своём сайте, это сигнал не «искать баг в коде», а «разбираться с ресурсами сервера, процессами и текущим состоянием инфраструктуры». Если же 503 видит ваш пользователь, а вы о нём не знаете — это отдельная проблема, о которой мы поговорим в конце.
Когда сервер отдаёт 503: основные причины
Причин немного, и почти все они сводятся к трём вещам: не хватает ресурсов, идёт обслуживание, или бэкенд за шлюзом перестал отвечать. Разберём каждую подробно.
1. Перегрузка сервера
Самая частая причина. Сервер исчерпал один из лимитов:
- все воркеры заняты. Веб-сервер (Nginx, Apache, Caddy) принимает соединения ограниченным числом процессов или потоков. Если все они заняты обработкой медленных запросов, новые запросы встают в очередь, а когда очередь переполняется — получают 503;
- кончилась память или CPU. Приложение отвечает слишком медленно, ОС начинает убивать процессы или они впадают в глубокий своп;
- исчерпан лимит подключений к базе данных или внешнему API. Приложение не может достучаться до зависимости и возвращает 503.
Показательный признак перегрузки — ошибка появляется и пропадает: в пиковые часы сайт «падает», а ночью работает.
2. Режим обслуживания (maintenance mode)
Многие фреймворки и CMS умеют штатно отдавать 503 во время обновлений. Laravel, WordPress-плагины, Drupal — у всех есть механизм «выключить сайт для посетителей, но оставить доступ администратору по IP». Это самый «правильный» 503: он спланирован, у него есть явное время начала и конца.
3. Деплой и перезапуск сервиса
Во время выкладки нового кода сервис на несколько секунд перестаёт отвечать. Если перед ним стоит прокси или балансировщик, в эти секунды он получает отказ соединения и превращает его в 503 для клиента. Чем дольше стартует приложение (миграции, прогрев кеша), тем дольше окно, в котором сайт отдаёт 503.
4. Лимиты и защита (rate limiting, WAF)
Сервер или защитный экран перед ним может сознательно отдавать 503, когда считает, что вы шлёте слишком много запросов. Это случается не только с ботами: агрессивный мониторинг, краулеры поисковиков или свой же внутренний скрипт могут упереться в лимит.
5. Бэкенд за шлюзом не отвечает
Если Nginx стоит перед PHP-FPM, Node.js, Gunicorn или любым другим приложением, и это приложение лежит, Nginx не может получить ответ. В такой конфигурации Nginx обычно отдаёт 502 Bad Gateway, но при определённых настройках (например, когда сокет существует, но сервис завис) клиент может увидеть именно 503.
Как быстро понять, что происходит
Прежде чем лезть в логи, соберите первичную картину по ответу сервера. Начните с простого запроса заголовков.
curl -I https://example.com
Разберём вывод построчно:
HTTP/2 503
server: nginx
retry-after: 120
content-type: text/html; charset=utf-8
HTTP/2 503— статус ответа. Сервер подтвердил: сейчас 503;server: nginx— ответ отдаёт именно Nginx, а не приложение за ним. Это уже подсказка: либо Nginx сам решил отдать 503 (лимиты, перегрузка), либо он не дождался ответа бэкенда;retry-after: 120— сервер предлагает повторить запрос через 120 секунд. Наличие этого заголовка — сильный маркер того, что 503 спланирован (обслуживание или деплой), а не аварийный;content-type: text/html— сервер вернул HTML-заглушку, а не пустой ответ.
Полезно также посмотреть полный обмен сообщениями, включая тело ответа:
curl -v https://example.com 2>&1 | head -50
Здесь -v включает подробный лог, 2>&1 перенаправляет его в stdout, а head -50 обрезает вывод. В логе вы увидите полный список заголовков и начало тела ответа — в нём часто бывает полезный текст: название хостинга, сообщение «maintenance in progress» или ссылка на статусную страницу.
Если 503 отдаётся не всегда, проверьте несколько раз подряд и замерьте время ответа:
for i in 1 2 3 4 5; do curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' https://example.com; done
Вывод может быть таким:
503 0.42s
200 0.38s
503 30.01s
200 0.41s
503 0.45s
Третий запрос занял 30 секунд и завершился 503 — классический паттерн: бэкенд висит на каком-то медленном запросе, шлюз ждёт до таймаута (30 секунд), не дожидается и отдаёт 503. Если в вашем выводе есть запросы с аномально большим time_total и статусом 503 — ищите медленный запрос или перегруженную базу, а не поломку в коде.
Таблица: симптом → причина → решение
Ниже — сводка типичных картин, с которыми приходит 503. Найдите свой симптом и двигайтесь по строке.
| Симптом | Вероятная причина | Что делать |
|---|---|---|
| 503 только в пиковые часы, ночью сайт работает | Перегрузка: кончились воркеры или память | Проверить нагрузку на CPU/RAM, число активных соединений, увеличить лимиты воркеров |
| 503 у всех, включая статику | Веб-сервер перегружен или вручную остановлен | Проверить статус сервиса веб-сервера, свободную память, перезапустить |
| 503 у всех, статика при этом открывается | Лежит бэкенд (PHP-FPM, Node, Gunicorn) | Проверить статус процесса бэкенда и логи |
503 с заголовком Retry-After |
Плановое обслуживание или деплой | Ничего не чинить — дождаться окончания работ, убедиться, что режим обслуживания снят |
| 503 только с вашего IP | Rate limiting / WAF / блокировка | Проверить лимиты, внести свой IP в исключения |
| 503 периодически, запросы с большим временем ответа | Медленный запрос или зависшая БД | Смотреть slow-лог, профилировать запросы, индексы |
| 503 сразу после деплоя | Сервис не успел стартовать | Увеличить таймаут ожидания бэкенда, настроить graceful restart |
| 503 на всех страницах после обновления CMS | Кривое обновление, конфликт плагинов | Откатить обновление, включить debug, смотреть логи приложения |
Разбираемся с конкретными стеками
Nginx + PHP-FPM
Самый частый сетап, и чаще всего 503 здесь — это PHP-FPM, который не успевает обрабатывать запросы. Проверьте, жив ли процесс:
systemctl status php8.2-fpm
Если процесс запущен, но отдаёт ошибки, посмотрите его лог:
tail -f /var/log/php8.2-fpm.log
Типичная запись, указывающая на исчерпание пула:
WARNING: [pool www] server reached pm.max_children setting (20), consider raising it
Здесь PHP-FPM прямо говорит: достигнут лимит pm.max_children — 20 дочерних процессов, и все заняты. Пока занят хотя бы один, новые запросы ждут; когда ждать больше некуда, клиент получает 503. Лечится увеличением лимита в конфиге пула (/etc/php/8.2/fpm/pool.d/www.conf):
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 25
Но повышать лимит вслепую нельзя: каждый процесс держит память. Правило простое — посчитайте, сколько памяти у вас свободно, и поделите на размер одного PHP-процесса. Например, если у сервера 4 ГБ свободной памяти, а один процесс занимает 80 МБ, безопасный максимум — около 40 процессов.
Nginx как шлюз перед приложением
Если Nginx проксирует запросы в Node.js, Python или другой сервис через proxy_pass, 503 может отдавать сам Nginx, когда не может подключиться к апстриму. Проверьте, доступен ли бэкенд на своём порту:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/
Если бэкенд не отвечает даже локально — проблема в приложении, а не в конфиге Nginx. Если отвечает, а через Nginx всё равно 503 — смотрите конфиг апстрима: не совпадает ли порт или сокет, не включён ли down у сервера.
Apache
В Apache 503 чаще всего связан с модулями и ограничениями. Два частых случая:
- включён модуль
mod_qosилиmod_evasive, который отдаёт 503 при превышении лимита соединений; - Apache слушает запрос, но не может перекинуть его обработчику (например, PHP как CGI завис).
Проверьте журнал ошибок:
tail -f /var/log/apache2/error.log
Записи вида server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting — прямое указание увеличить MaxRequestWorkers в конфиге MPM.
Контейнеры и оркестрация
Если сайт в Docker или Kubernetes, 503 обычно отдаёт балансировщик или ingress, когда под не отвечает. Проверьте здоровье пода:
kubectl get pods -n your-namespace
Состояние CrashLoopBackOff или Running, но с failing readiness probe — и есть причина. 503 приходит от ingress, который видит, что readiness-проба не проходит, и не отправляет трафик на под. Смотрите логи конкретного пода, а не балансировщика.
Плановое обслуживание: как отдавать 503 правильно
Отдельная тема — когда 503 вам нужен намеренно. Если вы обновляете сайт или базу, лучше самим показать посетителю аккуратную заглушку, чем позволить ему увидеть полуразобранный сайт или ошибку базы.
Правильный «плановый» 503 отвечает трём требованиям:
- Сервер отдаёт код 503, а не 200. Поисковики понимают 503 как «временно недоступно, зайдите позже» и не выкидывают страницу из индекса. Если вместо этого отдавать 200 с текстом «ведутся работы», поисковик закеширует заглушку вместо реальной страницы;
- Есть заголовок
Retry-After. Он подсказывает ботам, когда вернуться; - Администратор сохраняет доступ. Режим обслуживания не должен запирать вас самих.
В Laravel это делается одной командой:
php artisan down --retry=60
Флаг --retry=60 как раз добавляет заголовок Retry-After: 60. Когда работы закончены — php artisan up.
В Nginx простейший вариант — временно отдавать статическую заглушку вместо проксирования, а после окончания работ вернуть конфиг. Важно после снятия обслуживания проверить, что сайт реально ожил, — например, той же командой проверки доступности.
Как предотвратить 503
Разовые 503 во время плановых работ — нормальная часть эксплуатации. Проблема в тех 503, которые приходят внезапно и о которых вы узнаёте от клиента, а не из своей системы мониторинга.
Три вещи, которые стоит сделать:
- Следить за ресурсами. Настройте алерты на загрузку CPU, свободную память и число активных соединений веб-сервера. Перегрузка — главная причина внезапных 503, и она почти всегда нарастает постепенно: у вас есть окно в несколько минут, чтобы среагировать, если вы это видите;
- Мониторить доступность снаружи. Ошибка 503 — это то, что видит пользователь. Проверить, отдаёт ли ваш сайт 503 прямо сейчас, можно через проверку доступности сайта: сервис запрашивает страницу так, как это делает посетитель извне, и фиксирует код ответа;
- Настроить оповещения. Худший сценарий — 503, который висит часами, пока вы о нём не знаете. Внешний мониторинг с алертами на email ловит это за минуты, а не за часы.
Отдельно стоит следить за скоростью ответа: если время отклика растёт, а число 503 в логах увеличивается — сайт подходит к порогу перегрузки, и лучше устранить причину до того, как посетители начнут видеть заглушку.
Внутренний мониторинг инфраструктуры (например, Zabbix) хорошо показывает, что происходит с сервером изнутри — CPU, память, диск. Но он не видит картинку глазами пользователя: не может сказать, что именно отдаёт сайт наружу в данный момент. Поэтому внешняя проверка доступности дополняет, а не заменяет внутренний мониторинг.
Коротко
Ошибка 503 — это «сервер временно не может обработать запрос», а не «код сломан». В 9 из 10 случаев причина — перегрузка, плановое обслуживание или упавший бэкенд за шлюзом. Начните с заголовков ответа (curl -I) и логов веб-сервера — они почти всегда прямо называют причину. Если 503 спланирован, отдавайте его правильно: с кодом 503 и заголовком Retry-After, чтобы не навредить индексации.
Чтобы не узнавать о 503 от клиентов, проверяйте доступность сайта снаружи — начните с бесплатной проверки доступности. А если столкнулись с ошибкой 500, у нас есть отдельный разбор — ошибка 500 Internal Server Error: причины и решение.