Nginx Error: rewrite rule loop detected — Устранение зацикливания
При выполнении запроса веб-сервер аварийно возвращает статус 500 Internal Server Error. В файле error.log регистрируется зацикливание подсистемы переписывания адресов: rewrite rule loop detected in configuration block while processing URI или cycle while processing URI.
| Флаг Rewrite | Поведение парсера | Риск зацикливания |
|---|---|---|
last | Завершает текущий набор правил и перезапускает поиск location заново | Высокий при совпадении с тем же или родительским правилом |
break | Прекращает обработку правил модуля rewrite и остается в текущем location | Нулевой (цикл физически невозможен) |
| Без флага | Продолжает последовательное выполнение следующих правил rewrite | Средний при цепочечных заменах |
- Пользователь видит ошибку 500 после длительного ожидания или мгновенно по исчерпанию лимита 10 внутренних итераций.
- Включенный
rewrite_log on;демонстрирует многократную бесконечную трансформацию одной и той же строки адреса.
- Включите подробное логирование механизма Rewrite в блоке
serverдля поиска сбойного правила:error_log /var/log/nginx/error.log notice; rewrite_log on; - Изучите лог ошибок и определите зацикленное регулярное выражение:
sudo tail -n 30 /var/log/nginx/error.log | grep -E "rewritten|cycle" - Замените флаг
lastна флагbreakвнутри блоковlocation:location /download/ { # БЫЛО (вызывало повторный поиск location и цикл): # rewrite ^/download/(.*)$ /files/$1 last; # СТАЛО (останавливает цикл обработки): rewrite ^/download/(.*)$ /files/$1 break; root /var/www/storage; } - Убедитесь, что регулярное выражение не матчит результат собственной замены (например,
rewrite ^/(.*)$ /prefix/$1сопоставляется с/prefix/...до бесконечности). Добавьте исключение:rewrite ^/(?!prefix/)(.*)$ /prefix/$1 last; - Проверьте валидность файла конфигурации и примените:
sudo nginx -t && sudo systemctl reload nginx.
last используется преимущественно в контексте server, а флаг break — строго внутри контекста location. Использование last внутри location почти всегда приводит к скрытым петлям редиректов.Частые вопросы (FAQ)
Почему Nginx прекращает обработку ровно после 10 итераций?
Значение 10 является защитным лимитом (hardcoded limit), предотвращающим бесконечное зависание рабочего процесса воркера Nginx и 100% утилизацию ядер процессора.
Что показывает директива rewrite_log on?
Она выводит в error.log (на уровне notice) подробные шаги работы регулярных выражений: исходный URI, совпавшее правило и полученный в результате преобразования новый URI.
Чем отличается флаг redirect от permanent в rewrite?
Флаг redirect возвращает клиенту внешний HTTP-редирект с временным кодом 302. Флаг permanent возвращает постоянный редирект с кодом 301, который кэшируется браузером.
Как переписать URL без изменения адресной строки у пользователя?
Используйте внутреннее переписывание с флагом break внутри location или директиву try_files.