Ошибка 404 в WordPress: что проверить, если страницы и записи не открываются

Главная WordPress открывается, админка работает, но при переходе на запись, страницу, рубрику или раздел «Новости» сервер отвечает 404 Not Found. Иногда 404 появляется только у одного типа контента, а иногда перестают открываться почти все внутренние страницы сайта.

В такой ситуации сначала нужно понять, на каком уровне возникает 404.

Проверять удобно по цепочке:

URL → существует ли запись → простой ?p=ID → rewrite rules WordPress → Apache/Nginx → custom post type → конфликт slug → плагины → логи

Не начинайте с переустановки WordPress и не восстанавливайте базу из резервной копии, пока не установлена причина.

Основные проверки также помогут сопоставить проблему с диагностикой неработающего сайта WordPress, ошибкой 500 и критической ошибкой WordPress.

↑ К оглавлению

1. Сначала убедитесь, что это действительно HTTP 404

Сообщение «Страница не найдена» в браузере ещё не говорит, где возникла проблема.

Проверьте ответ сервера:

curl -s -o /dev/null -w '%{http_code}\n' \
  https://example.com/news/example-post/

Если ответ:

404

сервер действительно возвращает статус 404 Not Found.

Полезно также посмотреть заголовки:

curl -sI https://example.com/news/example-post/

Главная при этом может нормально отвечать:

curl -s -o /dev/null -w '%{http_code}\n' \
  https://example.com/

Например:

200

Получается характерная картина:

/                       → 200
/news/example-post/     → 404

Это уже сужает поиск.

WordPress запускается, но конкретный URL либо не попадает в правильное rewrite rule, либо после разбора запроса WordPress не находит подходящий объект.

Проверьте несколько URL

Не ограничивайтесь одной страницей.

Сравните:

главная
обычная запись
обычная страница
рубрика
архив
проблемные «Новости»

Например:

for url in \
  https://example.com/ \

  https://example.com/sample-page/ \
  https://example.com/category/news/ \
  https://example.com/news/test-post/
do
  curl -s -o /dev/null -w "%{http_code}  %{url_effective}\n" "$url"
done

Если 404 получает только один тип контента, это гораздо больше похоже на проблему его rewrite rules, чем на глобальную поломку WordPress.

↑ К оглавлению

2. Проверьте, существует ли запись в WordPress

Перед настройкой Nginx или .htaccess убедитесь, что сам объект действительно существует.

Если известен ID записи:

wp post get 123 \
  --fields=ID,post_title,post_status,post_type,post_name \
  --format=json

Нормальный опубликованный объект будет иметь примерно такие данные:

{
  "ID": 123,
  "post_title": "Новость",
  "post_status": "publish",
  "post_type": "post",
  "post_name": "novost"
}

Особенно проверьте:

post_status
post_type
post_name

Если запись находится в draft, pending или private, публичный URL может вести себя иначе, чем вы ожидаете.

Узнать текущий permalink через WordPress можно так:

wp eval 'echo get_permalink(123), PHP_EOL;'

Сравните полученный URL с тем, который открываете в браузере.

Быстрый тест через ?p=ID

Для обычной записи попробуйте:

https://example.com/?p=123

Если:

/?p=123                  → работает
/news/example-post/      → 404

это очень полезный диагностический результат.

Он означает, что:

  • WordPress видит запись;
  • база данных содержит объект;
  • WordPress способен его открыть;
  • проблема связана именно с красивым URL, rewrite rules или конфигурацией веб-сервера.

Не нужно в такой ситуации восстанавливать таблицу wp_posts.

Искать нужно дальше по цепочке маршрутизации URL.

↑ К оглавлению

Откройте:

Settings → Permalinks

или:

Настройки → Постоянные ссылки

Посмотрите текущую структуру URL.

Через WP-CLI:

wp option get permalink_structure

Например:

/%postname%/

Если проблема появилась после:

  • установки плагина;
  • добавления нового post type;
  • изменения структуры URL;
  • миграции;
  • изменения slug;
  • обновления темы;

rewrite rules могли оказаться устаревшими.

Сохраните постоянные ссылки

Один из штатных способов обновить rewrite rules:

  1. открыть Settings → Permalinks;
  2. ничего не менять;
  3. нажать Save Changes.

После этого снова проверьте URL.

Если 404 исчезла, причина была именно в rewrite rules.

Если правила регулярно ломаются снова, значит где-то есть:

  • плагин;
  • тема;
  • custom post type;
  • кастомный rewrite-код;

который управляет правилами неправильно.

Не вызывайте flush на каждой загрузке страницы

Существует:

flush_rewrite_rules();

но использовать эту функцию на каждом init или каждом page load нельзя.

Flush обычно требуется однократно после изменения набора правил.

↑ К оглавлению

4. Проверьте rewrite rules через WP-CLI

Посмотрите:

wp rewrite list

Для конкретного URL:

wp rewrite list --match='news/example-post'

Если WordPress находит правило, будет виден соответствующий match, query и источник правила.

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

news/([^/]+)/?
→ index.php?post_type=news&name=$matches[1]

Если подходящего правила нет, проверяйте регистрацию:

  • custom post type;
  • taxonomy;
  • rewrite slug;
  • endpoint;
  • plugin rewrite rules.

Обновить rules:

wp rewrite flush

Ожидаемо:

Success: Rewrite rules flushed.

После этого снова:

wp rewrite list --match='news/example-post'

Не запускать flush многократно без причины.

↑ К оглавлению

5. Apache: проверьте .htaccess и mod_rewrite

Для Apache красивые permalink URL обычно требуют корректной rewrite-конфигурации.

Проверить модуль:

apache2ctl -M | grep rewrite

или:

apachectl -M | grep rewrite

Ищите:

rewrite_module

Проверьте .htaccess

Перед изменением:

cp .htaccess .htaccess.backup

Не копируйте .htaccess с чужого сайта вслепую.

.htaccess существует, но Apache его игнорирует

Проверьте <Directory>.

Для rewrite-директив из .htaccess сервер должен разрешать соответствующие overrides, например:

<Directory /var/www/example>
    AllowOverride FileInfo
</Directory>

Если:

AllowOverride None

.htaccess не применяется.

Характерный симптом:

главная             → работает
/?p=123             → работает

/example-post/      → 404

После изменения Apache-конфигурации сначала:

apachectl configtest

или:

apache2ctl configtest

и только после успешного теста применять reload.

↑ К оглавлению

6. Nginx: .htaccess здесь не поможет

Nginx .htaccess не использует.

Посмотреть итоговую конфигурацию:

nginx -T

Найти try_files:

nginx -T 2>&1 | grep -n 'try_files'

Для WordPress запрос к несуществующему физическому файлу должен в итоге попадать в WordPress.

Конфигурация может использовать, например:

location / {
    try_files $uri $uri/ @wordpress;
}

с дальнейшей передачей запроса из named location в index.php.

Не вставляйте чужой location / поверх рабочего production-конфига.

Показательный симптом:

/index.php?p=123       → работает
/example-post/         → 404

После изменения:

nginx -t

и только после успешной проверки reload.

↑ К оглавлению

7. Почему все новости WordPress выдают ошибку 404

Сценарий:

обычные страницы → работают
обычные записи   → работают
все новости      → 404

«Новости» могут быть Custom Post Type.

Например:

news
portfolio
cases

products
events

Посмотрите post types:

wp post-type list \
  --fields=name,label,public,hierarchical

Если нужного типа нет, проверьте плагин или тему, которые должны его регистрировать.

Проверьте записи:

wp post list \
  --post_type=news \
  --fields=ID,post_title,post_name,post_status,url

Если записи существуют и опубликованы, но URL дают 404, проверяйте rewrite:

wp rewrite list --match='news/example'

После регистрации нового post type при необходимости:

wp rewrite flush

затем:

wp rewrite list --match='news/example'

Если plugin, который регистрировал post_type = news, отключён, сами записи могут остаться в базе, но WordPress больше не будет знать соответствующий post type и rewrite rules.

Не импортировать записи заново до проверки регистрации типа.

↑ К оглавлению

8. Проверьте конфликт slug

Возможен конфликт, например:

post type: news
rewrite slug: news

и одновременно обычная страница:

/news/

Проверьте страницы:

wp post list \
  --post_type=page \
  --fields=ID,post_title,post_name,url

И нужный post type:

wp post list \
  --post_type=news \
  --fields=ID,post_title,post_name,url

Ищите конфликты:

post_name
rewrite base
archive slug
page slug

После исправления slug обновите rewrite rules.

↑ К оглавлению

9. Проверьте плагины и тему только после проверки маршрутизации

Не начинать с отключения всех плагинов на production.

Особенно подозрительны плагины:

  • permalink;
  • redirects;
  • SEO;
  • multilingual URL;
  • custom post types;
  • security;
  • memberships;
  • caching;
  • routing.

Для поиска вмешательства в URL:

grep -RIn \
  --exclude-dir=node_modules \
  --exclude-dir=vendor \
  -E 'add_rewrite_rule|rewrite_rules_array|register_post_type|register_taxonomy|flush_rewrite_rules' \
  wp-content/themes \
  wp-content/plugins \
  wp-content/mu-plugins

Команда не утверждает, что найденный код ошибочный.

Она показывает, кто вмешивается в routing.

Проверку конфликтов проводить предпочтительно:

production
↓
backup
↓
staging
↓
воспроизвести 404
↓
отключать только подозрительные компоненты
↑ К оглавлению

10. Если 404 появилась после миграции

Проверить:

wp option get home
wp option get siteurl

После Apache → Nginx старый .htaccess проблему не решает.

После Nginx → Apache старый Nginx config не заменяет mod_rewrite.

Проверить document root.

Nginx:

nginx -T 2>&1 | grep -nE 'server_name|root|try_files'

Apache:

apache2ctl -S

или:

apachectl -S
↑ К оглавлению

11. Не путайте настоящую 404 с неправильным редиректом

Иногда:

301

или:

302

а конечный URL уже возвращает:

404

Проверить цепочку:

curl -sIL https://example.com/news/example/

или:

curl -sL \
  -o /dev/null \
  -w 'final=%{url_effective} status=%{http_code}\n' \
  https://example.com/news/example/

Если исходный URL уходит на неправильный адрес, проверяйте:

  • redirect plugin;
  • canonical redire cts;
  • SEO plugin;
  • web-server redirects;
  • старые migration rules.
↑ К оглавлению

12. Если старый URL действительно больше не существует

Не каждая 404 является ошибкой.

Запись могла быть:

  • удалена;
  • перенесена;
  • объединена;
  • получила новый slug.

Если замены нет, корректный 404 может быть нормальным.

Если есть новый соответствующий URL — использовать точечный 301:

старый URL
→
соответствующий новый URL

Не перенаправлять все 404 на homepage.

↑ К оглавлению

13. Посмотрите логи в момент запроса

Nginx:

tail -f /var/log/nginx/access.log \
             /var/log/nginx/error.log

Apache Debian/Ubuntu:

tail -f /var/log/apache2/access.log \
             /var/log/apache2/error.log

Проверять:

  • status;
  • virtual host;
  • PHP errors;
  • попал ли запрос в index.php.

Отсутствие PHP fatal в wp-content/debug.log не доказывает правильность rewrite rules.

↑ К оглавлению

14. Быстрая диагностика через SSH

HTTP

curl -s -o /dev/null -w '%{http_code}\n' \
  https://example.com/news/example/

Объект

wp post get 123 \
  --fields=ID,post_status,post_type,post_name \
  --format=json

Правильный URL

wp eval 'echo get_permalink(123), PHP_EOL;'

Permalink structure

wp option get permalink_structure

Rewrite rule

wp rewrite list --match='news/example'

Flush при необходимости

wp rewrite flush

Повторная проверка

curl -s -o /dev/null -w '%{http_code}\n' \
  https://example.com/news/example/

Логика:

объект есть?
↓
какой URL генерирует WordPress?
↓
есть ли rule?
↓
доходит ли URL до WordPress?
↓
что отвечает сервер после flush?
↑ К оглавлению

15. Короткий алгоритм: что проверять по порядку

Шаг 1

Определить масштаб:

главная
страницы
записи
рубрики
конкретный post type

Шаг 2

HTTP:

curl -s -o /dev/null -w '%{http_code}\n' URL

Шаг 3

Объект:

wp post get ID

Шаг 4

Простой URL:

/?p=ID

Шаг 5

Структура:

wp option get permalink_structure

Шаг 6

Rewrite:

wp rewrite list --match='problem/url'

Шаг 7

При необходимости один раз:

wp rewrite flush

или:

Settings → Permalinks

Шаг 8

Определить server:

Apache:

mod_rewrite
.htaccess
AllowOverride

Nginx:

try_files
index.php
server block

Шаг 9

Если ломается один type:

register_post_type
rewrite slug
archive
slug conflicts
plugin/theme

Шаг 10

Воспроизвести проблему одновременно с logs.

↑ К оглавлению

Почему после сохранения постоянных ссылок 404 исчезает?

WordPress хранит сгенерированные rewrite rules и использует их для преобразования красивого URL во внутренний запрос.

После появления нового типа записей или изменения permalink-структуры правила могут нуждаться в обновлении.

Сохранение:

Settings → Permalinks

перестраивает rewrite rules.

Если это помогло один раз — нормально.

Если 404 постоянно возвращается и приходится регулярно нажимать Save, нужно искать код или плагин, который неправильно управляет rewrite rules.

↑ К оглавлению

Частые вопросы

Почему главная WordPress работает, а остальные страницы выдают 404?

Одна из первых проверок — красивые постоянные ссылки. Если URL вида /?p=123 работает, а /example-post/ возвращает 404, проверьте rewrite rules и конфигурацию Apache или Nginx.

Почему все новости WordPress выдают ошибку 404?

Если «Новости» реализованы как Custom Post Type, проверьте, зарегистрирован ли этот post type, есть ли его rewrite rule и нет ли конфликта rewrite slug с обычной страницей. После изменения регистрации может потребоваться однократное обновление rewrite rules.

Поможет ли сохранение постоянных ссылок?

Да, если проблема вызвана устаревшими rewrite rules. Но если Apache игнорирует .htaccess, Nginx неправильно настроен или custom post type вообще не регистрируется, одно сохранение Permalinks не устранит первопричину.

Нужно ли редактировать .htaccess, если сайт работает на Nginx?

Нет. Nginx не использует .htaccess. Для него нужно проверять серверную конфигурацию, прежде всего обработку try_files и передачу запроса в WordPress index.php.

↑ К оглавлению

Главное

Ошибка 404 в WordPress не означает автоматически, что запись удалена или база данных повреждена.

Если внутренние страницы перестали открываться, сначала определите границу:

HTTP
↓
объект WordPress
↓
простой ?p=ID
↓
permalink
↓
rewrite rule
↓
Apache / Nginx
↓
Custom Post Type
↓
slug conflict
↓
plugin/theme
↓
logs

Особенно полезен тест:

/?p=123 работает
+
/example-post/ отдаёт 404

Он сразу переводит диагностику от базы и контента к системе постоянных ссылок и веб-серверу.

А если 404 выдаёт только один раздел, например все новости, не нужно чинить весь WordPress. Проверьте post type, его rewrite rules и URL-префикс.

Цель — не просто добиться ответа 200, а точно понять, почему конкретный URL перестал сопоставляться с нужной записью WordPress.

↑ К оглавлению

Частые вопросы

Почему главная WordPress работает, а остальные страницы выдают 404?

Одна из первых проверок — красивые постоянные ссылки. Если URL вида `/?p=123` работает, а `/example-post/` возвращает 404, проверьте rewrite rules и конфигурацию Apache или Nginx.

Почему все новости WordPress выдают ошибку 404?

Если «Новости» реализованы как Custom Post Type, проверьте, зарегистрирован ли этот post type, есть ли его rewrite rule и нет ли конфликта rewrite slug с обычной страницей. После изменения регистрации может потребоваться однократное обновление rewrite rules.

Поможет ли сохранение постоянных ссылок?

Да, если проблема вызвана устаревшими rewrite rules. Но если Apache игнорирует `.htaccess`, Nginx неправильно настроен или custom post type вообще не регистрируется, одно сохранение Permalinks не устранит первопричину.

Нужно ли редактировать `.htaccess`, если сайт работает на Nginx?

Нет. Nginx не использует `.htaccess`. Для него нужно проверять серверную конфигурацию, прежде всего обработку `try_files` и передачу запроса в WordPress `index.php`.

↑ К оглавлению

Нужна помощь с WordPress?

Если после последовательной проверки причина остаётся неясной, можно обратиться за диагностикой WordPress. Также доступны все инструкции WebFixer24.

↑ К оглавлению