Nginx Error 500: subrequest limit exceeded — Причины и решение
Клиент сталкивается с ошибкой 500 Internal Server Error при обработке составных веб-страниц или запросов, использующих аутентификацию. В журнале error.log Nginx появляется запись: subrequest limit exceeded while processing uri "/sub-auth" или subrequest loop in "/include/block".
| Параметр Nginx | Жесткий предел ядра | Причина исчерпания |
|---|---|---|
NGX_HTTP_MAX_SUBREQUESTS | 50 вложенных запросов | Рекурсивные вызовы внутри SSI (Server Side Includes) |
auth_request loop | Превышение предела | Обработчик аутентификации сам обращается к защищенному location |
Каскадный error_page | Превышение предела | Обработка ошибки 500 перенаправляется на URL, генерирующий новую ошибку 500 |
- Nginx принудительно прерывает выполнение цепочки и немедленно возвращает клиенту код 500.
- В логах фиксируются десятки однотипных вложенных запросов с одинаковым
request_id.
- Изучите лог ошибок для выявления циклического URI:
sudo tail -n 50 /var/log/nginx/error.log | grep "subrequest limit" - Если используется модуль
auth_request, убедитесь, что эндпоинт авторизации изолирован и не требует авторизации внутри себя:location = /auth-verify { internal; proxy_pass http://auth_service:8080/verify; # Отключаем auth_request внутри самого эндпоинта аутентификации: auth_request off; proxy_pass_request_body off; proxy_set_header Content-Length ""; } - Если используются директивы SSI (
ssi on;), проверьте шаблоны на наличие взаимного включения файлов:<!--#include virtual="/file1.html" -->, включающего обратноfile2.html. - Проверьте директивы
error_page. Убедитесь, что страница ошибки не перенаправляется на скрипт, вызывающий ту же ошибку:# ПРАВИЛЬНО (отдача статичного HTML без вложенных проксирований): error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; internal; } - Протестируйте и перезагрузите конфигурацию:
sudo nginx -t && sudo systemctl reload nginx.
NGX_HTTP_MAX_SUBREQUESTS = 50 зашита в C-исходники Nginx для предотвращения исчерпания стека памяти воркера и защиты от DoS-атак на процесс парсинга SSI.Частые вопросы (FAQ)
Что такое subrequest (подзапрос) в терминологии Nginx?
Подзапрос — это внутренний HTTP-запрос, генерируемый Nginx внутри основного клиентского запроса для получения фрагментов данных (например, SSI include, auth_request или зеркалирование mirror).
Можно ли увеличить лимит подзапросов через nginx.conf?
Нет, директивы для этого нет. Лимит задается макросом NGX_HTTP_MAX_SUBREQUESTS в исходном коде src/http/ngx_http_core_module.h и требует перекомпиляции Nginx.
Что означает директива internal в блоке location?
Директива internal указывает, что данный location доступен исключительно для внутренних подзапросов Nginx (редиректов, auth_request, ssi) и закрыт от прямых обращений извне.
Как модуль mirror может вызывать subrequest limit exceeded?
Если в location, куда дублируется трафик директивой mirror, также включена директива mirror на исходный location, возникает бесконечный цикл клонирования подзапросов.