Apache LinuxApache HTTP Server 2.4

Apache: ErrorDocument возвращает HTTP 200 вместо исходного кода 404

  • Обновлено
  • Чтение ≈ 4 минуты

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

Как заставить пользовательскую страницу ошибки Apache сохранять исходный код 404/403, не маскируя ошибки под ответ 200.

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

#Что означает проблема

В Apache локальная директива ErrorDocument 404 /errors/404.html обычно сохраняет исходный код 404. Если клиент в итоге видит 200, причиной может быть внешний URL с отдельным перенаправлением, код PHP-страницы, переадресация из .htaccess или проверка конечного ответа после перехода. Сама красивая страница с текстом «404» ещё не означает верный HTTP-статус.

#Как различить причины

Возможная причинаКак узнатьЧто делать
Внешний ErrorDocumentErrorDocument задан полным URL вместо локального пути; Apache отправляет клиента на другой адрес.В заголовках сначала появляется 302, затем 200 целевой страницы.Использовать локальный путь для ошибки, не внешний URL.
Запрос забирает маршрутизатор PHPRewriteRule направляет отсутствующий URL в index.php, который возвращает 200.Apache не создаёт 404; код формирует приложение.При отсутствии маршрута выставить статус 404 на уровне приложения.
Проверяется последний ответ после -LКлиент автоматически следует переадресации на страницу ошибок.Без -L код 302/404, с -L — 200.Сравнить начальный и конечный ответы.

#Подробная диагностика и устранение

  1. Создайте безопасный проверочный запросВозьмите несуществующий адрес внутри публичного раздела, например https://example.com/__not_found_check_20261102, подставив домен и убедившись, что такого маршрута нет. Не удаляйте и не переименовывайте реальные файлы ради проверки. В браузере через F12 → «Сеть» найдите запрос и запишите именно HTTP-статус, а не текст на странице.
  2. Проверьте статус и промежуточные ответы отдельноВ терминале компьютера выполните curl -sS -D - -o /dev/null https://example.com/__not_found_check_20261102 — покажет заголовки первого ответа. Затем сравните с curl -sS -L -D - -o /dev/null ... — покажет промежуточные заголовки при переходах. Если видите 302 → 200, нужно устранить именно перенаправление вместо локальной ошибки.
  3. Убедитесь, что Apache вообще обрабатывает ошибкуНа сервере через SSH вызовите sudo apache2ctl -S, найдите нужный VirtualHost и откройте его конфигурацию. Просмотрите ErrorDocument в нём и .htaccess. Если Nginx/CDN перехватывает 404 или приложение всегда возвращает 200, изменения ErrorDocument Apache не затронут внешний ответ, пока не изменится соответствующий слой.
  4. Проверьте синтаксис ErrorDocumentДля локального документа указывайте путь от корня адресного пространства, начиная с /, например ErrorDocument 404 /errors/404.html. Это не абсолютный путь в файловой системе и не URL с https://. Убедитесь, что файл существует внутри DocumentRoot, доступен посетителю и не попадает под повторное правило ошибок.
  5. Отделите ошибки PHP-приложения от файловых 404Если все URL маршрутизируются в index.php, для заведомо неизвестного маршрута PHP должен выставлять код через http_response_code(404) до отправки заголовков и показывать нужную страницу. Не применяйте этот код ко всем успешным маршрутам. Если приложение возвращает 200, Apache не сможет «угадать», что смысл страницы — ошибка.
  6. Исправьте только подтверждённое правилоСкопируйте файл VirtualHost или .htaccess перед правкой. Замените внешний ErrorDocument на локальный либо настройте правильный код ответа в собственном PHP-приложении, если оно и есть источник. Не отключайте модуль перенаправлений целиком, не отправляйте все неизвестные адреса на главную со статусом 200: это ухудшает диагностику и индексацию.
  7. Протестируйте конфигурацию и перезагрузите Apache при необходимостиДля правки главного файла выполните sudo apache2ctl configtest и при Syntax OK команду sudo systemctl reload apache2. Изменения .htaccess обычно читаются при запросе и не требуют reload, но их синтаксическая ошибка может сразу дать 500. При такой ошибке верните скопированный файл и проверьте журнал Apache.
  8. Сравните три класса ответов и откатПроверьте заведомо существующую страницу (200), несуществующий URL (404) и закрытый ресурс, разрешённый для тестирования (403). Отдельно проверьте отсутствующую страницу ошибок, чтобы не создать второй 404. Если после правки 404 стал 500, откатите изменение и читайте error.log; не превращайте любую ошибку в ответ 200.
  9. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1В обычном терминале без sudo.
    Linux · Терминал (Bash)Команда
    В обычном терминале без sudo. Подставьте свой домен; -L следует переходам, поэтому показывает дополнительный ответ.
    curl -sS -D - -o /dev/null https://example.com/__not_found_check_20261102
    curl -sS -L -D - -o /dev/null https://example.com/__not_found_check_20261102
    Вариант 2Локальный URL внутри сайта; указанный файл должен реально существовать и открываться без перенаправления.
    Текст
    Локальный URL внутри сайта; указанный файл должен реально существовать и открываться без перенаправления.
    ErrorDocument 404 /errors/404.html

#Как проверить результат

Результат правильный, когда отсутствующий адрес возвращает 404 в первом HTTP-ответе, документ ошибки читается, реальные страницы продолжают выдавать ожидаемый 200, а ограничения доступа не смягчены.

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

Если виден 200, проследите всю цепочку заголовков, код PHP-контроллера и возможный перехват в Nginx. Не правьте ErrorDocument Apache, если проблема вызвана приложением или CDN.

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

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

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