Записи WordPress отдают 404, а главная страница работает
Если главная страница открывается нормально, но каждая отдельная запись и страница отдаёт 404, значит правила перезаписи URL, на которые опирается WordPress, отсутствуют или повреждены в вашем
Опубликовано
Если главная страница открывается нормально, но каждая отдельная запись и страница отдаёт 404, значит правила перезаписи URL, на которые опирается WordPress, отсутствуют или повреждены в вашем файле .htaccess. Самое быстрое решение: зайдите в Настройки → Постоянные ссылки в консоли WordPress и нажмите Сохранить изменения, ничего не меняя. Это заставит WordPress заново сгенерировать блок правил перезаписи. Если 404 никуда не делись, значит ваш .htaccess недоступен для записи веб-сервером, Apache настроен игнорировать его, либо у вас Nginx (который вообще не использует .htaccess).
Почему главная работает, а записи — нет
Главная страница работает, потому что запрос к / обслуживается напрямую из index.php в корне сайта. Никакой перезаписи не требуется.
Запрос к /2026/my-post/ — это другое дело. Такого пути на диске в виде реальной папки не существует. Чтобы WordPress мог его обработать, Apache должен внутренне перенаправить запрос на index.php, после чего WordPress читает REQUEST_URI, сопоставляет его с правилами перезаписи, хранящимися в опции rewrite_rules в базе данных, разбирает переменные запроса (WP::parse_request()) и загружает нужную запись.
Передача запроса от Apache к index.php — это и есть та часть, которая ломается. Она целиком зависит от вот этого блока в .htaccess:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Две строки RewriteCond говорят: если запрошенный путь не является реальным файлом (!-f) и не является реальным каталогом (!-d), направь его на index.php. Уберите этот блок — и Apache начнёт искать буквальный каталог /2026/my-post/, не найдёт его и вернёт собственную ошибку 404 — ещё до того, как WordPress вообще увидит запрос.
Почему WordPress перезаписывает .htaccess, когда вы сохраняете постоянные ссылки
Именно эту часть большинство руководств пропускает. Когда вы нажимаете «Сохранить» на экране постоянных ссылок, WordPress вызывает flush_rewrite_rules(). На Apache с доступным для записи .htaccess это запускает save_mod_rewrite_rules(), который заново генерирует блок выше через WP_Rewrite::mod_rewrite_rules() и записывает его обратно с помощью insert_with_markers().
insert_with_markers() трогает только строки между # BEGIN WordPress и # END WordPress. Всё, что снаружи этих маркеров, остаётся нетронутым. Всё, что внутри, отбрасывается и переписывается заново. Более новые версии WordPress даже выводят предупреждение прямо в файле:
Any changes to the directives between these markers will be overwritten.
Так что «WordPress перезаписывает мой .htaccess» — это правда, но с оговоркой: он переписывает только свой собственный помеченный маркерами блок, и только когда файл доступен для записи. Если файл недоступен для записи, сохранение молча ничего не пишет на диск. WordPress показывает жёлтое уведомление на экране постоянных ссылок с предложением вставить правила вручную, и если вы это уведомление пропустите, ваш блок правил так и останется отсутствующим, а каждая запись продолжит отдавать 404.
Как это исправить, по порядку
1. Пересохраните постоянные ссылки. Настройки → Постоянные ссылки → Сохранить изменения. Никаких правок не нужно. Это заново запустит сброс правил и перепишет блок. Так решается большинство случаев, в том числе устаревшие правила после переноса сайта.
2. Проверьте, что .htaccess существует и доступен для записи. Он лежит в той же папке, что и wp-config.php. Это файл, имя которого начинается с точки, поэтому включите «показывать скрытые файлы» в вашем FTP-клиенте или используйте:
ls -la /path/to/wordpress/.htaccess
Если его нет, создайте и вставьте правильный блок. Если ваша установка находится в подкаталоге, RewriteBase и конечная цель перезаписи должны соответствовать этому пути — неправильно указанный путь и есть самая частая причина, по которой вставленный вручную блок всё равно отдаёт 404. Наш генератор .htaccess собирает точный блок под путь вашей установки, чтобы вам не приходилось гадать.
3. Убедитесь, что Apache разрешено читать .htaccess. Если у виртуального хоста стоит AllowOverride None, Apache полностью игнорирует файл независимо от его содержимого. Вам нужен AllowOverride All (или как минимум FileInfo) для каталога WordPress. Это находится в конфигурации сервера, а не в .htaccess, поэтому требует доступа к серверу:
<Directory /var/www/html>
AllowOverride All
</Directory>
4. Убедитесь, что mod_rewrite включён. На Debian/Ubuntu:
sudo a2enmod rewrite
sudo systemctl restart apache2
5. На Nginx никакого .htaccess нет. Правила перезаписи прописываются в блоке server:
location / {
try_files $uri $uri/ /index.php?$args;
}
Быстрая диагностика: чей это 404?
Посмотрите на страницу 404. Если это неоформленная страница ошибки Apache или хостинга, значит Apache вообще не дошёл до WordPress — это проблема с .htaccess или конфигурацией сервера (шаги 2–4). Если это оформленная страница 404 вашего шаблона, значит WordPress получает запрос, но не может его сопоставить — правила в базе данных устарели, и решение — пересохранить постоянные ссылки (шаг 1). Одно это различие экономит большинству людей час гаданий.
Чего делать не нужно
Не отключайте сначала все плагины. Симптом в чистом виде «записи отдают 404, главная работает» — это проблема перезаписи, а не конфликт плагинов. Отключение плагинов — рефлекторный совет на форумах, и он почти никогда не относится к этой ситуации.
Не делайте chmod 777 для вашего .htaccess. WordPress нужно, чтобы файл был доступен для записи пользователю веб-сервера, а это не то же самое, что доступ на запись для всех. 644 с правильным владельцем — это нормально и безопасно; 777 — это дыра в безопасности, которая маршрутизацию всё равно не починит.
Не вставляйте собственные правила перезаписи внутрь маркеров # BEGIN WordPress / # END WordPress. Они будут стёрты при следующем сохранении постоянных ссылок кем угодно. Размещайте свои директивы выше строки # BEGIN WordPress.
Не переустанавливайте WordPress. Файлы ядра в порядке. Это один недостающий блок текста, а не повреждённая установка.
Не вините свой шаблон. Маршрутизация постоянных ссылок — это ядро WordPress. Шаблон не может её сломать и не может её починить.
Всё ещё не получается?
Если вы пересохранили постоянные ссылки, убедились, что блок присутствует и доступен для записи, и выставили AllowOverride All, то остаётся один подозреваемый — плагин безопасности или правило на уровне хостинга, которое втихую пересоздаёт или блокирует .htaccess. Проверьте время изменения файла сразу после сохранения постоянных ссылок — если оно не изменилось, значит что-то блокирует запись. Сгенерируйте чистый блок с помощью генератора .htaccess, вставьте его и проверьте заново с жёсткой перезагрузкой страницы.