WordPress の投稿だけ 404 になる(トップページは正常)場合の対処法
トップページは問題なく表示されるのに、個別の投稿や固定ページがすべて 404 になる場合、WordPress が依存している URL のリライトルールが .htaccess から失われているか、壊れています。
公開
トップページは問題なく表示されるのに、個別の投稿や固定ページがすべて 404 になる場合、WordPress が依存している URL のリライトルールが .htaccess から失われているか、壊れています。最も手っ取り早い対処法は、wp-admin の 設定 → パーマリンク を開き、何も変更せずに 変更を保存 をクリックすることです。これで WordPress はリライトブロックを再生成します。それでも 404 が続く場合は、.htaccess が Web サーバーから書き込めない状態になっているか、Apache が .htaccess を無視する設定になっているか、あるいは(.htaccess をそもそも使わない)Nginx で運用しているかのいずれかです。
トップページは表示されるのに投稿は表示されない理由
トップページが表示されるのは、/ へのリクエストがドキュメントルートの 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
2 行の RewriteCond は「リクエストされたパスが実在するファイルでなく(!-f)、実在するディレクトリでもない(!-d)場合は、index.php へ送る」という意味です。このブロックを削除すると、Apache は /2026/my-post/ という実在のディレクトリを探し、見つからず、WordPress がリクエストを受け取る前に Apache 自身の 404 を返してしまいます。
パーマリンクを保存すると WordPress が .htaccess を上書きする理由
これはほとんどのガイドが省略している部分です。パーマリンク画面で保存をクリックすると、WordPress は flush_rewrite_rules() を呼び出します。.htaccess が書き込み可能な Apache 環境では、これが 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 は内容にかかわらずファイルを完全に無視します。WordPress のディレクトリに対して AllowOverride All(少なくとも FileInfo)が必要です。これは .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)が解決策です。この 1 つの見分けだけで、多くの人が 1 時間の当てずっぽうを省けます。
やってはいけないこと
まずすべてのプラグインを停止する、はNG。 「投稿は 404、トップページは正常」という純粋な症状はリライトの問題であって、プラグインの競合ではありません。プラグインの無効化はフォーラムでの反射的な回答ですが、この問題にはまず効きません。
.htaccess を chmod 777 にする、はNG。 WordPress が必要とするのは Web サーバーのユーザー による書き込み権限であり、これは誰でも書き込める状態とは別物です。正しい所有者のもとで 644 にすれば十分かつ安全です。777 はセキュリティホールであり、そもそもルーティングは直りません。
# BEGIN WordPress / # END WordPress マーカーの内側にカスタムのリライトルールを貼り付ける、はNG。 次に誰かがパーマリンクを保存した時点で消去されます。カスタムのディレクティブは # BEGIN WordPress の行の 上 に置いてください。
WordPress を再インストールする、はNG。 コアファイルは無事です。これはテキストのブロックが 1 つ欠けているだけであって、インストールの破損ではありません。
テーマのせいにする、はNG。 パーマリンクのルーティングは WordPress コアの機能です。テーマがこれを引き起こすことも、直すこともできません。
それでも解決しない場合
パーマリンクを再保存し、ブロックが存在して書き込み可能であることを確認し、AllowOverride All も設定したのに直らない場合、残る容疑者はセキュリティプラグインか、あなたの知らないところで .htaccess を再生成またはロックしているホスト側のルールです。パーマリンク保存の直後にファイルの更新日時を確認してください。変わっていなければ、何かが書き込みを妨げています。.htaccess 書き方ツール でクリーンなブロックを生成して貼り付け、スーパーリロード(ハードリフレッシュ)で再テストしてください。