Веб-серверы 11 мин чтения 2026-09-25

Циклические редиректы и ошибка ERR_TOO_MANY_REDIRECTS: поиск причин бесконечной цепочки 301/302 и устранение сбоя в Nginx, Cloudflare и WordPress

Сайт внезапно перестал открываться с ошибкой «Слишком много перенаправлений»? Разбираем 4 главные ловушки: конфликт Cloudflare Flexible SSL, отсутствие переменной HTTPS в FastCGI WordPress, войну слэшей и настраиваем монолитный редирект в Nginx.

Инженерная редакция SysKit Проверено инженерами SysKit.ru

Ситуация, знакомая каждому администратору серверов: после подключения SSL-сертификата, миграции за Cloudflare или правок в конфигурации Nginx сайт внезапно перестает открываться. Вместо контента браузер моментально выдает сообщение «ERR_TOO_MANY_REDIRECTS» (в Яндекс Браузере — «Сайт выполнил слишком много перенаправлений», в Firefox — «Страница не перенаправляется должным образом»).

Для коммерческого проекта каждая минута такой аварии означает прямые убытки: рекламный трафик сливается впустую, пользователи уходят к конкурентам, а краулеры поисковых систем фиксируют недоступность страниц. Ниже мы детально разберем физику возникновения циклических перенаправлений, рассмотрим 4 главные ловушки в веб-серверах и дадим готовые, выверенные конфигурации для их устранения.

1. Анатомия проблемы: почему браузер выдает ERR_TOO_MANY_REDIRECTS

Механизм HTTP-перенаправлений прост: клиент делает запрос к ресурсу А, сервер возвращает ответ с кодом 301 Moved Permanently, 302 Found, 307 Temporary Redirect или 308 Permanent Redirect и указывает целевой адрес в заголовке Location. Браузер автоматически отправляет новый запрос по указанному адресу.

Циклический редирект (Redirect Loop) возникает тогда, когда правила перенаправления образуют замкнутый круг:

  • Прямой цикл (A ↔ B): Страница http://site.ru/ перенаправляет на https://site.ru/, а та в свою очередь отсылает обратно на http://site.ru/.
  • Многозвенная петля (A → B → C → A): Перенаправление между версиями с www, протоколами и завершающими слэшами.
  • Саморекурсия (A → A): Страница возвращает заголовок Location, указывающий на саму себя.

Современные браузеры содержат внутренний лимит на глубину перенаправлений (обычно 20 переходов в Google Chrome и Яндекс Браузере). Как только счетчик превышает порог, клиент разрывает соединение и выводит ошибку ERR_TOO_MANY_REDIRECTS во избежание зависания системы.

Чем опасны длинные цепочки редиректов для SEO

Даже если редирект в итоге успешно завершается (например, в 3–5 шагов), каждый промежуточный HTTP-запрос добавляет 150–400 мс задержки из-за повторных сетевых рукопожатий (RTT). Поисковые роботы Яндекса и Google имеют строгий лимит краулингового бюджета: натыкаясь на цепочки из 3+ редиректов, краулер откладывает обход или вовсе выбрасывает страницу из приоритетной очереди индексации.

2. Экспресс-диагностика цепочки за 30 секунд через curl и утилиты

Главная ошибка при диагностике — проверять редиректы в основном профиле рабочего браузера. Браузеры агрессивно кэшируют постоянные ответы 301 и заголовок HSTS (Strict-Transport-Security) на уровне дискового кэша. Даже если вы исправите ошибку на сервере, ваш браузер продолжит крутить старый цикл из кэша.

Первый шаг профессиональной диагностики — чистый CLI-запрос через утилиту curl с флагами -I (только заголовки) и -L (следовать за редиректами):

# Просмотр полной цепочки HTTP-ответов и заголовков Location
curl -IL https://syskit.ru

Если на сервере возникла циклическая петля, curl выведет цепочку повторяющихся блоков и прервется с ошибкой:

HTTP/1.1 301 Moved Permanently
Location: https://syskit.ru/
...
HTTP/1.1 301 Moved Permanently
Location: http://syskit.ru/
...
curl: (47) Maximum (50) redirects followed

Для быстрой сводки без чтения сотен строк логов используйте однострочник, выводящий количество звеньев цепочки и финальный URL:

curl -ILsS https://syskit.ru -o /dev/null -w "Финальный код: %{http_code}
Редиректов пройдено: %{num_redirects}
Итоговый адрес: %{url_effective}
Время проверки: %{time_total}с
"

Если доступ к консоли сервера в данный момент ограничен или нужно быстро проверить сайт со смартфона, используйте наш бесплатный онлайн-инструмент:

Онлайн-инспектор выполняет пошаговую трассировку всех прыжков, показывает точные HTTP-статусы каждого узла (301, 302, 307, 308) и фиксирует промежуточные заголовки Location и Server.

3. Ловушка №1: Cloudflare Flexible SSL и бесконечный цикл между шлюзом и VDS

Это самая распространенная причина сбоя при подключении Cloudflare. Она возникает из-за фундаментального непонимания разницы между режимами шифрования трафика.

Режим Cloudflare SSL Связка: Клиент ↔ Cloudflare Связка: Cloudflare ↔ Сервер VDS Риск циклической петли
Off HTTP (без шифрования) HTTP (порт 80) Низкий (нет SSL)
Flexible HTTPS (защищено) HTTP (незащищенный порт 80) КРИТИЧЕСКИЙ (гарантированный цикл при редиректе в Nginx)
Full HTTPS (защищено) HTTPS (порт 443, любой сертификат) Безопасно
Full (strict) HTTPS (защищено) HTTPS (порт 443, валидный доверенный SSL) Идеально (рекомендация)

Как рождается вечная петля:

  1. Пользователь открывает https://domain.com в браузере. Cloudflare принимает защищенное соединение.
  2. В режиме Flexible Cloudflare считает, что на исходном сервере VDS нет SSL, и идет за контентом по открытому протоколу http://domain.com:80.
  3. На VDS веб-сервер Nginx настроен по стандартному шаблону: перенаправлять весь входящий порт 80 на HTTPS (return 301 https://$host$request_uri;).
  4. Nginx возвращает этот редирект прокси-серверу Cloudflare.
  5. Cloudflare передает редирект клиенту или повторно запрашивает адрес, снова обращаясь к порту 80. Круг замыкается мгновенно.

Решение проблемы:

  1. В панели управления Cloudflare перейдите в раздел SSL/TLS → Overview.
  2. Переключите режим шифрования с Flexible на Full (strict) (или Full, если на VDS установлен самоподписанный сертификат).
  3. Выпустите бесплатный сертификат Let's Encrypt на сервере или создайте бесплатный Cloudflare Origin Certificate (на 15 лет) и пропишите его в Nginx. Проверить корректность цепочки можно через SSL-чекер.

Если по каким-то причинам вам временно необходим режим Flexible, научите Nginx определять исходный протокол клиента по служебному заголовку Cloudflare X-Forwarded-Proto:

# Корректная обработка HTTPS за Cloudflare Flexible
server {
    listen 80;
    server_name domain.com www.domain.com;

    # Редиректим только если клиент пришел по обычному HTTP
    if ($http_x_forwarded_proto = "http") {
        return 301 https://$host$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

4. Ловушка №2: WordPress за Reverse-Proxy и переменная HTTPS в FastCGI

Вторая классическая ловушка возникает в CMS WordPress, Bitrix или Laravel, работающих за обратным прокси-сервером (Nginx, Traefik, Caddy или Docker-контейнер). Внутренний механизм WordPress использует функцию is_ssl() для проверки текущего протокола. Функция возвращает true только если переменная окружения $_SERVER['HTTPS'] равна строке 'on' или порт сервера равен 443.

Если Nginx принимает HTTPS-трафик на порту 443, но проксирует его в контейнер PHP-FPM или Docker через порт 80 без передачи параметров безопасности, PHP-скрипт считает, что соединение не защищено. Встроенная функция WordPress canonical_redirect() видит, что в базе задан адрес https://site.ru, и выдает заголовок Location: https://site.ru/. Следующий запрос приходит на HTTPS, снова попадает в PHP как HTTP — и сайт падает в бесконечный редирект.

Шаг 1: Правильная передача заголовков в блоке Nginx FastCGI

В блоке location ~ .php$ вашего Nginx обязательно передавайте индикатор HTTPS в PHP-FPM:

location ~ .php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    # КРИТИЧЕСКИ ВАЖНО: передаем флаг защищенного соединения
    fastcgi_param HTTPS $https if_not_empty;
    fastcgi_param HTTP_X_FORWARDED_PROTO $scheme;
}

Если Nginx работает в качестве frontend-прокси перед внутренним Apache или Docker-контейнером с WordPress, передавайте заголовки обратного прокси:

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Шаг 2: Страховочный фикс в wp-config.php

Откройте файл конфигурации сайта wp-config.php и добавьте в самое начало (до вызова wp-settings.php) обработчик обратного прокси:

<?php
// Распознавание HTTPS за обратным прокси / Cloudflare
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

// Жесткая фиксация URL для исключения расхождений в базе данных
define('WP_HOME', 'https://domain.com');
define('WP_SITEURL', 'https://domain.com');

Этот простой фрагмент из трех строк предотвращает до 90% всех сбоев с циклическими перенаправлениями в экосистеме WordPress.

5. Ловушка №3: Война слэшей на конце URL (Trailing Slash loop)

Конфликт завершающего слэша возникает, когда конфигурация веб-сервера и правила маршрутизации CMS имеют противоположные взгляды на каноничность адреса:

  • Nginx считает каноническим адрес без слэша (/catalog) и принудительно обрезает слэш.
  • CMS или SEO-плагин считает каноническим адрес со слэшем (/catalog/) и шлет редирект обратно.

Результат — бесконечный пинг-понг между /catalog и /catalog/ со статусами 301.

Опасное правило, вызывающее зацикливание:

# ОШИБКА: слепое удаление слэша без проверки файловой системы
rewrite ^/(.*)/$ /$1 permanent;

Если по пути /catalog/ на диске существует реальная директория, модуль Nginx http_core автоматически допишет слэш обратно, вызвав циклическую блокировку. Конфигурацию необходимо строить с проверкой условий:

# Корректное приведение к единому стандарту (со слэшем на конце)
# Если запрошен файл или папка — не вмешиваемся
if (!-e $request_filename) {
    rewrite ^([^.?]*[^/])$ $1/ permanent;
}

Совет инженера: согласованность с CMS

Никогда не настраивайте глобальные правила слэшей в Nginx в отрыве от настроек вашей системы управления. Если в настройках постоянных ссылок WordPress задана структура /%postname%/, веб-сервер не должен иметь правил, удаляющих слэш. Всегда проверяйте поведение сайта после любых правок через проверку редиректов.

6. Канонический монолитный редирект в Nginx: склейка без промежуточных звеньев

Типичная неоптимальная архитектура сервера часто выглядит так: запрос http://www.site.ru/page перенаправляется на https://www.site.ru/page (шаг 1), затем на https://site.ru/page (шаг 2), и только потом на https://site.ru/page/ (шаг 3). Три редиректа вместо одного!

Правильный инженерный подход — монолитный редирект в 1 шаг: любой некорректный вариант (незащищенный протокол HTTP или зеркало www) обязан немедленно перенаправляться на канонический адрес без промежуточных остановок.

Вот эталонный production-конфиг Nginx для Ubuntu 24.04 / Debian 12:

# 1. Единый порт 80: перенаправляем весь HTTP сразу на финальный канонический HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name domain.com www.domain.com;

    # Служебный путь для валидации сертификатов Certbot Let's Encrypt
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # Мгновенный монолитный редирект на канонический домен
    location / {
        return 301 https://domain.com$request_uri;
    }
}

# 2. Неканоническое зеркало HTTPS (www): редирект на чистый домен
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name www.domain.com;

    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

    return 301 https://domain.com$request_uri;
}

# 3. Основной рабочий виртуальный хост (Канонический адрес)
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name domain.com;

    root /var/www/domain.com/public_html;
    index index.php index.html;

    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # HSTS: строгая защита от даунгрейда протокола (включать после полной проверки SSL!)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
    }

    location ~ /.ht {
        deny all;
    }
}

Если вы используете современный веб-сервер Caddy 2 вместо Nginx, канонический редирект решается еще лаконичнее в Caddyfile:

# Caddyfile: автоматический SSL и редирект с www
www.domain.com {
    redir https://domain.com{uri} permanent
}

domain.com {
    root * /var/www/domain.com/public_html
    file_server
    php_fastcgi unix//run/php/php8.3-fpm.sock
}

Для генерации индивидуальных конфигурационных файлов под вашу версию Nginx, Caddy или Apache воспользуйтесь нашим интерактивным разделом готовых конфигураций серверов.

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

Выбор редакции
⚡

Timeweb Cloud — Быстрые NVMe VDS

Отказоустойчивая инфраструктура с быстрыми NVMe-накопителями и каналом до 1 Гбит/с, идеально подходящая для Nginx и высоконагруженных сайтов.

Конфигурация
1 vCPU 3.3 ГГц • 1 ГБ RAM • 15 ГБ NVMe • Трафик без лимита
Премиум Tier III
🔷

Selectel — Надежные облачные серверы

Корпоративный уровень надежности, дата-центры Tier III, резервирование сетевых маршрутов и аппаратная защита от DDoS-атак L3/L4.

Конфигурация
1 vCPU • 2 ГБ RAM • 30 ГБ NVMe • Резервирование каналов
Простота для CMS
🟠

Beget — Оптимально под WordPress и Nginx

Моментальный запуск VDS, удобная панель управления сервером и предустановленные быстрые конфигурации с Nginx и FastCGI-кэшем.

Конфигурация
1 vCPU • 1 ГБ RAM • 15 ГБ NVMe • Бесплатные бэкапы

7. Чек-лист инженера по устранению редирект-петель

Если сайт упал с ошибкой ERR_TOO_MANY_REDIRECTS, пройдите по алгоритму быстрой реанимации:

  1. Тестируйте без кэша: используйте терминальную команду curl -IL https://ваш-домен.ru или инкогнито-окно браузера. Помните: 301-редиректы намертво оседают в кэше браузера.
  2. Проверьте Cloudflare SSL: если сайт за Cloudflare, переключите режим с Flexible на Full (strict). В 90% случаев это решает проблему на месте.
  3. Проверьте протокол в CMS: при использовании Nginx как reverse-proxy убедитесь, что в конфигурации присутствует директива fastcgi_param HTTPS on; или proxy_set_header X-Forwarded-Proto https;.
  4. Сверьте адреса в базе данных: убедитесь, что значения siteurl и home в таблице wp_options (или аналогичной таблице вашей CMS) содержат единый протокол https:// и канонический домен.
  5. Проверьте файлы .htaccess: если используется связка Nginx + Apache, убедитесь, что в .htaccess нет старых конфликтующих правил перезаписи RewriteRule, дублирующих логику Nginx.
  6. Исключите петли слэшей: убедитесь, что правила веб-сервера для слэша на конце URL совпадают со структурой ссылок движка сайта.

Проверьте статус ваших редиректов прямо сейчас

Убедитесь, что все зеркала вашего сайта корректно склеены, сервер возвращает статус 200 OK в один шаг, а краулеры поисковых систем не застревают в многозвенных цепочках перенаправлений.

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Чем отличается редирект 301 от 302 при возникновении ошибки циклического перенаправления?
Код 301 (Moved Permanently) кэшируется браузерами клиентов и поисковыми роботами на длительный срок на диске. Если вы допустили ошибку в правиле с кодом 301, пользователи продолжат попадать в цикл даже после исправления на сервере, пока не очистят кэш браузера. Код 302 (Found / Временный) не кэшируется клиентами, поэтому при отладке и тестировании новых правил редиректа рекомендуется сначала использовать статус 302, а переключать на постоянный 301 только после полной проверки.
Почему ошибка ERR_TOO_MANY_REDIRECTS возникает только в мобильной версии сайта?
Частая причина — некорректная настройка мобильного поддомена (m.site.ru) или определение User-Agent в Nginx. Если скрипт определяет мобильный браузер и отсылает его на поддомен m.site.ru, а конфиг поддомена m.site.ru перенаправляет трафик обратно на адаптивную версию основного сайта, возникает циклическая петля. Проверяйте заголовки ответа через curl с подменой User-Agent смартфона: curl -IL -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)" https://domain.com.
Как очистить закэшированный браузером постоянный 301-редирект?
Для принудительного сброса закэшированного 301-редиректа в Google Chrome или Яндекс Браузере откройте инструменты разработчика (F12), перейдите на вкладку Network и установите галочку «Disable cache». Не закрывая панель DevTools, выполните жесткую перезагрузку страницы сочетанием клавиш Ctrl + F5 (или Shift + F5). В крайнем случае очистите кэш изображений и файлов в настройках конфиденциальности браузера за последний час.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи