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