Nginx Linux

Nginx: в proxy_cache нет HIT из-за Set-Cookie

  • Обновлено
  • Чтение ≈ 4 минуты
  • Нужны права администратора

Краткий ответ

При стандартном proxy_cache ответ с Set-Cookie обычно не сохраняется. Это защищает пользователя от выдачи другому посетителю персональной страницы и помогает понять, почему виден повторный MISS.

В этой статье
  1. Что означает и когда возникает ошибка
  2. Причины и как их различить
  3. Пошаговая диагностика и исправление
  4. Проверка результата
  5. Если проблема осталась

#Что означает и когда возникает ошибка

Нельзя добиваться HIT ценой кэширования страниц авторизации, корзины или личного кабинета. Сначала установите, является ли адрес действительно общедоступным, затем выясните, кто добавляет Set-Cookie и какие ещё заголовки управляют кэшем.

#Причины и как их различить

Возможная причинаКак узнатьЧто делать
Ответ содержит Set-CookieПриложение выдаёт cookie каждому посетителю, даже на публичной странице.В заголовках ответа GET виден Set-Cookie; повторный запрос не попадает в кэш.Убрать ненужную cookie именно у публичной страницы на стороне приложения.
Ответ помечен как персональныйCache-Control: private/no-store, авторизация, сеанс или Vary делают кэширование неподходящим.В запросе Authorization/Cookie, ответ отличается для разных пользователей.Оставить обход кэша, не принуждать к HIT.
Обход кэша обусловлен настройкамиВ Nginx указаны proxy_cache_bypass, proxy_no_cache или разный proxy_cache_key.Публичный ответ одинаковый, Set-Cookie отсутствует, но статус MISS/BYPASS.Сравнить реально действующую конфигурацию и ключи.

#Пошаговая диагностика и исправление

  1. Определите безопасный URL для проверкиВыберите публичную статическую или обезличенную страницу, одинаковую для всех. Не используйте личный кабинет, оплату, корзину, профиль или API с пользовательскими данными. Запишите её полный URL, затем откройте на клиентском компьютере терминал и выполните curl -sS -D - -o /dev/null https://example.com/public/. Посмотрите Set-Cookie, Cache-Control, Vary, Expires, если они есть. Замените адрес на свой; не передавайте реальные cookie и токены.
  2. Проверьте, настроен ли вообще proxy_cacheВойдите на сервер через SSH, выполните sudo nginx -T 2>&1 | grep -nE "proxy_cache|proxy_no_cache|proxy_cache_bypass|proxy_cache_key|proxy_ignore_headers|add_header". Убедитесь, что URL действительно обрабатывает proxy_pass и используется созданная зона из proxy_cache_path. Если он отдаётся FastCGI, смотрите отдельные fastcgi_cache*, а не proxy_cache. Если кэш выключен, отсутствие HIT нормально.
  3. Сравните два одинаковых запросаДважды выполните GET к проверяемому URL без авторизации. Если сервер уже отдаёт диагностический заголовок кэша, сравните его значения. Если не отдаёт, администратор может временно добавить диагностический заголовок add_header X-Cache-Status $upstream_cache_status always; только к тестовому публичному местоположению: он может раскрывать внутренние детали и должен быть удалён после диагностики. Ожидаемое состояние для кэшируемого объекта обычно MISS затем HIT; BYPASS и пустое значение требуют дальнейшего анализа.
  4. Выясните, почему приложение ставит cookieВ ответе с публичной страницы посмотрите, что является причиной установки сеанса: плагин статистики, компонент авторизации, корзина, приложение или middleware. Исправляйте выдачу cookie в приложении: не создавайте сессию для действительно обезличенного URL. На рабочем сайте изменение сначала проверьте на тестовой копии и убедитесь, что авторизация и корзина продолжают работать.
  5. Не используйте опасное игнорирование Set-CookieНе добавляйте proxy_ignore_headers Set-Cookie; ради HIT без полного понимания: Nginx может кэшировать ответ с персональными данными и выдать их другому посетителю. Точно так же не скрывайте cookie от пользователя простым proxy_hide_header как замену исправлению приложения. Для персональных запросов оставляйте proxy_no_cache и proxy_cache_bypass либо полностью исключайте такой location из кэша.
  6. Если меняли конфигурацию — проверьте еёСделайте резервную копию фактического файла конфигурации сайта, изменяйте одну директиву за раз, затем выполните sudo nginx -t и при успехе sudo systemctl reload nginx. Если результат плохой, восстановите скопированный файл и повторите тест и reload. Не очищайте весь кэш сайта без необходимости: это может вызвать всплеск нагрузки на приложение.
  7. Убедитесь в правильной изоляции пользователейСделайте два запроса к публичному URL без cookie и проверьте, что со второго запроса возможен HIT. Затем проверьте авторизованный URL в отдельных тестовых аккаунтах: он не должен показывать чужие данные и не должен быть общим HIT. Если тест вызывает сомнение, отключите кэш для затронутого местоположения и передайте проверку специалисту по безопасности.
  8. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Без sudo на своём компьютере.
    Linux · Терминал (Bash)Команда
    Без sudo на своём компьютере. GET с выводом заголовков; замените адрес на публичную страницу своего сайта.
    curl -sS -D - -o /dev/null https://example.com/public/
    Вариант 2Чтение конфигурации через SSH на своём сервере; не публикуйте весь вывод.
    Linux · Терминал (Bash)КомандаНужен sudo
    Чтение конфигурации через SSH на своём сервере; не публикуйте весь вывод.
    sudo nginx -T 2>&1 | grep -nE "proxy_cache|proxy_no_cache|proxy_cache_bypass|proxy_ignore_headers"
    Вариант 3Временная диагностика только для доверенной тестовой среды/публичного URL; не показатель сам по себе, если …
    Nginx
    Временная диагностика только для доверенной тестовой среды/публичного URL; не показатель сам по себе, если кэш на другом уровне.
    add_header X-Cache-Status $upstream_cache_status always;

#Проверка результата

Успех: общедоступная страница после прогрева может давать HIT, а персональные ответы гарантированно обходят общий кэш; журнал не показывает ошибки доступа.

#Если проблема осталась

Сохраните дату, точный URL без паролей и токенов, код ответа, обезличенные строки error.log и access.log за это время и перечень уже сделанных изменений. Сравните работу при обращении через публичный адрес и через внутренний балансировщик, если он есть. Если причину пока не удалось подтвердить, восстановите исходную конфигурацию из копии и передайте эти сведения администратору или разработчику приложения; не меняйте несколько параметров одновременно.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.