2026年8月22日

2026年8月22日

WordPress移行後に404エラーが出るときの直し方|.htaccess・パーマリンク・URL置換

WordPressをサーバー移転やドメイン変更で移したあとに「トップページは開くのに、記事や固定ページがすべて404になる」という症状は、多くの場合、URLの書き換え(リライト)がWebサーバー側で働いていないことが原因です。データベースに古いURLが残っていると、別の症状(旧ドメインへ飛ばされる、画像が出ない)も重なります。

この記事では、症状から原因を切り分け、Apache・Nginxそれぞれの設定、パーマリンクの再保存、データベース内のURL置換の順に説明します。コマンド例は2026年10月時点のWP-CLI 2系、Apache 2.4、Nginxを前提にしています。

作業の前にバックアップを取る

URLの置換はデータベースを書き換えます。失敗したときに戻せるよう、先に書き出しておきます。

# WordPress のディレクトリで実行する
cd /var/www/html
wp db export ~/before-fix-404.sql

症状から原因を切り分ける

症状 考えられる原因
トップページは開くが、記事・固定ページ・カテゴリーが404 .htaccess が無い、Apacheが .htaccess を読んでいない、mod_rewrite が無効、Nginxに try_files が無い
ページを開くと旧ドメインへ転送される home・siteurl の値、または wp-config.php の WP_HOME・WP_SITEURL が旧ドメインのまま
ページは開くが、画像や内部リンクが旧ドメインを向いている 本文やウィジェット、テーマ設定に旧URLが残っている
サブディレクトリに移したら404 .htaccess の RewriteBase と転送先、またはNginxの location が旧パスのまま

切り分けの近道は、パーマリンクを使わないURLで開いてみることです。https://新ドメイン/?p=記事ID で記事が表示されるなら、記事のデータは移行できており、問題はURLの書き換えにあります。記事IDは管理画面の投稿一覧で編集リンクにマウスを重ねると post=123 の形で確認できます。

home と siteurl を確認する

最初に、サイトのURLとして登録されている値を確認します。

wp option get home
wp option get siteurl

旧ドメインや旧パスが出た場合は、新しい値に更新します。

wp option update home 'https://new-domain.example'
wp option update siteurl 'https://new-domain.example'

値が正しいのに旧ドメインへ転送される場合は、wp-config.php に次の定数が書かれていないかを確認します。定数があると、データベースの値より優先されます。

define( 'WP_HOME', 'https://new-domain.example' );
define( 'WP_SITEURL', 'https://new-domain.example' );

旧ドメインのまま書かれていれば新しい値に直すか、行ごと削除してデータベースの値を使います。2つの設定の違いはWordPressアドレスとサイトアドレスの違いで説明しています。

Apacheの場合:.htaccess とサーバー設定を確認する

.htaccess があるか

FTPクライアントの多くは、名前が . で始まるファイルを初期設定で表示しません。そのため、移行の際に .htaccess だけがコピーされていないことがあります。新しいサーバーのWordPressのディレクトリで確認します。

ls -la /var/www/html/.htaccess
cat /var/www/html/.htaccess

WordPress本体が書き込む部分は、# BEGIN WordPress と # END WordPress の間です。ルートにインストールした場合は次の内容になります。

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

ファイルが無い場合や中身が違う場合は、後述の「パーマリンクを保存し直す」で作り直せます。手で作る場合は上の内容で保存し、パーミッションを644にします。

Apacheが .htaccess を読んでいるか

自分で構築したVPSやクラウドのサーバーでは、Apacheの設定で .htaccess が無視されていることがよくあります。Apache 2.4の AllowOverride の初期値は None で、この場合 .htaccess の内容は読まれません。UbuntuやDebianの初期設定でも、/etc/apache2/apache2.conf の /var/www/ は AllowOverride None になっています。

WordPressを置いたディレクトリの設定(/etc/apache2/apache2.conf やバーチャルホストの設定ファイル)を、次のように変更します。

<Directory /var/www/html>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

RewriteEngine などのリライト用の命令を .htaccess で使うには、AllowOverride に少なくとも FileInfo が含まれている必要があります。All はその条件を満たします。

mod_rewrite が有効か

# 読み込まれているモジュールに rewrite があるか
apachectl -M | grep rewrite

# 無い場合は有効にする(Ubuntu・Debian)
sudo a2enmod rewrite

# 設定の文法を確認してから反映する
sudo apachectl configtest
sudo systemctl reload apache2

apachectl -M の結果に rewrite_module が出れば有効です。共用のレンタルサーバーでは、これらの設定はサーバー会社側で済んでいるため、.htaccess の有無と中身だけを確認します。

Nginxの場合:try_files を確認する

Nginxは .htaccess を読みません。パーマリンクを動かすには、サーバーの設定にWordPress用の try_files が必要です。WordPressの公式ドキュメントでは、次の形が示されています。

location / {
    try_files $uri $uri/ /index.php?$args;
}

旧サーバーがApacheで新サーバーがNginxの場合、この設定が無いと、トップページ以外がすべて404になります。設定を変えたら、文法を確認してから反映します。

sudo nginx -t
sudo systemctl reload nginx

NginxでのWordPressの設定全体はNginxでWordPressを動かす設定で説明しています。

パーマリンクを保存し直す

サーバーの設定が整ったら、WordPress側のリライトルールを作り直します。管理画面で行う場合は次のとおりです。

  1. 管理画面の「設定」→「パーマリンク」を開く
  2. 設定を変えずに「変更を保存」を押す

保存すると、データベースのリライトルールが作り直されます。Apacheで .htaccess に書き込める場合は、# BEGIN WordPress から # END WordPress の部分も書き直されます。書き込めない場合は、画面に .htaccess に書く内容が表示されるので、その内容を手で貼り付けます。

WP-CLIで行う場合は、次のコマンドです。

# 現在のパーマリンク構造を確認する(空ならパーマリンクを使っていない)
wp option get permalink_structure

# リライトルールを作り直す
wp rewrite flush

wp rewrite flush --hard は .htaccess も書き直すオプションですが、WP-CLIから .htaccess を作るには、WP-CLIの設定ファイル(wp-cli.yml)に次の記述が必要です。シングルサイトでのみ動きます。

apache_modules:
  - mod_rewrite

この設定が無いと、データベースのルールだけが作り直され、.htaccess は書き換わりません。迷ったら管理画面から保存する方法を使います。

データベース内の旧URLを置き換える

ドメインやディレクトリが変わった場合は、本文・ウィジェット・テーマの設定などに旧URLが残ります。WordPressの設定値にはPHPのシリアライズ形式で保存されたものがあり、文字数がデータに含まれているため、SQLの REPLACE で書き換えると壊れることがあります。WP-CLIの wp search-replace はシリアライズされた値も正しく書き換えます。

まず --dry-run で、どのテーブルで何件置き換わるかを確認します。

wp search-replace 'https://old-domain.example' 'https://new-domain.example' \
    --all-tables --skip-columns=guid --dry-run

件数に問題がなければ、--dry-run を外して実行します。旧サイトでhttpのURLも混在していた場合は、httpの側も置き換えます。

wp search-replace 'https://old-domain.example' 'https://new-domain.example' \
    --all-tables --skip-columns=guid

wp search-replace 'http://old-domain.example' 'https://new-domain.example' \
    --all-tables --skip-columns=guid

オプションの意味は次のとおりです。

オプション 意味
--dry-run 置換せず、置き換わる件数だけを表示する
--all-tables WordPressに登録されたテーブルだけでなく、データベース内のすべてのテーブルを対象にする。同じデータベースに別のサイトのテーブルがある場合は、代わりに --all-tables-with-prefix を使う
--skip-columns=guid 投稿の guid 列を書き換えない。WordPressの公式ドキュメントは、guid はフィードリーダーが記事を識別するための値なので変更しないよう案内している
--precise SQLではなくPHPで1行ずつ処理する。取りこぼしが減るが遅くなる。通常は付けなくてよい

置換のあと、同じコマンドを --dry-run 付きでもう一度実行し、置き換わる件数が0になっていれば完了です。wp search-replace の詳しい使い方はWP-CLIのsearch-replaceコマンドにまとめています。

最後にキャッシュを消します。

wp cache flush

キャッシュ系のプラグインやCDNを使っている場合は、それぞれの画面からもキャッシュを削除します。

サブディレクトリに移した場合

https://example.com/ から https://example.com/blog/ のように、WordPressをサブディレクトリに移した場合は、.htaccess の RewriteBase と最後の転送先もディレクトリに合わせます。

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress

この .htaccess は /blog/ ディレクトリの中に置きます。Nginxでは location と転送先をディレクトリに合わせます。

location /blog/ {
    try_files $uri $uri/ /blog/index.php?$args;
}

あわせて、home と siteurl を https://example.com/blog に更新し、データベース内の旧URLも前の節の手順で置き換えます。

直ったかを確かめる

# サイトのURL
wp option get home
wp option get siteurl

# パーマリンク構造
wp option get permalink_structure

# 記事のURLが200を返すか(URLは実在する記事に置き換える)
curl -s -o /dev/null -w '%{http_code}\n' https://new-domain.example/sample-post/

ブラウザで確認する場合は、以前に旧ドメインへの転送を記憶していることがあるため、プライベートウィンドウで開くと結果が分かりやすくなります。

まとめ

  • トップページだけ開いて他が404なら、まずリライトの設定を疑う。?p=記事ID で開ければデータは無事
  • Apacheは .htaccess の有無、AllowOverride、mod_rewrite の3点を確認する。Nginxは try_files を確認する
  • サーバー設定を直したら、「設定」→「パーマリンク」で「変更を保存」を押してルールを作り直す
  • 旧URLは wp search-replace で --dry-run から始めて置き換え、guid 列は対象から外す
  • サブディレクトリに移した場合は、RewriteBase と転送先、home・siteurl をディレクトリに合わせる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲