Nginx: proxy_pass cannot have URI part in location regex — Решение
При проверке файла конфигурации командой nginx -t или попытке перезапуска веб-сервера процесс завершается критической синтаксической ошибкой: nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside-named-location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/sites-enabled/default:42.
| Тип Location | Пример директивы | Допустимость URI в proxy_pass |
|---|---|---|
| Префиксный (обычный) | location /api/ | Разрешено: proxy_pass http://127.0.0.1:8000/v1/; |
| Регулярное выражение (Regex) | location ~ ^/api/(.*) | ЗАПРЕЩЕНО: proxy_pass http://127.0.0.1:8000/v1/; |
| Именованный (Named) | location @fallback | ЗАПРЕЩЕНО: proxy_pass http://127.0.0.1:8000/app; |
- Nginx полностью блокирует применение новой конфигурации до устранения синтаксического конфликта.
- Сбой возникает при попытке модифицировать путь запроса внутри regex location средствами самого
proxy_pass.
- Вариант 1 (Использование Rewrite — Рекомендуемый): Уберите URI-часть из директивы
proxy_passи выполните нормализацию пути через директивуrewrite ... break:location ~* ^/api/(.*)$ { # Переписываем URI перед передачей в бэкенд: rewrite ^/api/(.*)$ /v1/$1 break; # proxy_pass БЕЗ указания пути на конце: proxy_pass http://127.0.0.1:8000; } - Вариант 2 (Использование переменных): Сформируйте целевой адрес через переменную — это заставит Nginx использовать переданный URI динамически:
location ~* ^/service-(?<section>[a-z]+)/(?<rest>.*)$ { proxy_pass http://backend_pool/$section/$rest$is_args$args; } - Вариант 3 (Переход на префиксный location): Если регулярное выражение не обязательно, замените его на обычный строковый префикс:
location /api/ { # В стандартном location добавление слэша на конце разрешено: proxy_pass http://127.0.0.1:8000/v1/; } - Проверьте валидность исправленной конфигурации:
sudo nginx -t - Примените настройки:
sudo systemctl reload nginx.
rewrite.Частые вопросы (FAQ)
Что считается 'URI part' в директиве proxy_pass?
Любой символ после имени хоста или порта. Например, в 'http://127.0.0.1:8080/' слэш '/' на конце уже является URI частью. Строка 'http://127.0.0.1:8080' URI части не имеет.
Почему флаг break обязателен в блоке rewrite внутри location?
Флаг break прекращает выполнение директив rewrite и передает измененный URI напрямую в proxy_pass. Без флага break Nginx перезапустит поиск нового location (флаг last), что приведет к ошибке 404 или циклу.
Работает ли URI part внутри именованных location (@named)?
Нет. Внутри именованных location (например, @fallback) директива proxy_pass также обязана быть строго без URI пути.
Теряются ли GET-параметры при использовании rewrite break?
Нет, аргументы запроса ($args) автоматически прикрепляются к новому URI, если в конце правила rewrite не стоит знак вопроса '?'.