2026年5月25日
2026年5月25日
Apacheでカスタム404エラーページを設定する方法(ErrorDocumentとWordPressの使い分け)
Apacheでカスタム404ページを出すには ErrorDocument 404 /404.html のようにサイト内のパスを指定します。ただしWordPressサイトでは、多くの404はApacheではなくWordPress(テーマの404テンプレート)が返しているため、ErrorDocumentを書いても表示が変わらないことがあります。この記事では、ErrorDocumentの正しい書き方、WordPressとの役割分担、ステータスコードが404のまま返っているかの確認方法を順に説明します。
404ページを出しているのは誰かを先に確かめる
WordPress標準の .htaccess には、実在しないファイルやディレクトリへのリクエストをすべて index.php に渡すリライトルールが入っています。
# BEGIN WordPress の中身(抜粋)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
このため、/no-such-page/ のような存在しないURLはApacheの404処理まで届かず、WordPressが404を判定し、テーマの 404.php(ブロックテーマなら404テンプレート)を表示します。ApacheのErrorDocumentが使われるのは、次のような場面です。
- WordPressのリライトが効いていないディレクトリ(別アプリ、静的ファイルだけの領域など)
- リライトより前にApacheが拒否・エラーを返したとき(403、413、500、503など)
- WordPressに渡さずApacheで404を返すように設定したリクエスト(後述の静的ファイル)
「404ページのデザインを変えたい」が目的なら、多くの場合はテーマの404テンプレートを編集するほうが正解です。Apache側の設定は、WordPressが関与しない範囲のエラー表示を整えるために使う、と考えると混乱しません。
ErrorDocumentの基本的な書き方
設定場所
ErrorDocumentは、サーバー設定(httpd.conf、VirtualHost)でも .htaccess でも書けます。.htaccess で使う場合は、そのディレクトリに AllowOverride FileInfo 以上が許可されている必要があります。VPSなどで設定ファイルを触れるなら、VirtualHostに書くほうが管理しやすく、処理も軽くなります。
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com/public
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 503 /errors/503.html
</VirtualHost>
サイト内パスで書く理由
ErrorDocumentの値には、サイト内のパス(/ で始まる)、外部URL、文字列の3種類を書けます。404で外部URL(https:// から始まる形)を指定すると、Apacheはエラーページへ「リダイレクト」するため、ブラウザや検索エンジンが受け取るステータスコードは404ではなく302になります。
# 良い例:ステータスは404のまま、中身だけ差し替わる
ErrorDocument 404 /errors/404.html
# 避けたい例:302リダイレクトになり、404として扱われない
ErrorDocument 404 https://example.com/errors/404.html
# 文字列を直接返す例(短い案内だけでよい場合)
ErrorDocument 404 "お探しのページは見つかりませんでした。"
存在しないページが302で別URLに飛び、そこが200で表示されると、Googleなどからはエラーが「ソフト404」として扱われる原因になります。エラーページはサイト内パスで指定するのが基本です。
エラーページ側の注意点
エラーページのHTMLは、どのURLで表示されても崩れないように作ります。たとえば /blog/2020/old-post.png の404として表示されたとき、CSSを css/style.css のような相対パスで読み込んでいると、/blog/2020/css/style.css を探しに行って見た目が崩れます。CSSや画像は /errors/404.css のように / から始まるパスで指定してください。
また、エラーページそのものが見つからないと、Apacheは既定のエラーメッセージに加えて「ErrorDocumentの処理中にも404が発生した」旨を表示します。ファイルの置き場所とパーミッション(Apacheユーザーが読めること)を確認します。
WordPressに渡さず静的ファイルの404を返す
画像やCSSのURLが間違っているだけでも、標準のリライトルールではWordPress本体が読み込まれ、PHPとデータベースの処理が走ります。古い画像URLへの大量アクセスやボットの探索が続くと、無駄な負荷になります。存在しない静的ファイルだけはApacheで404を返し、軽量なErrorDocumentを表示させる方法があります。
# .htaccess の「# BEGIN WordPress」より上に書く
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(?:jpe?g|png|gif|webp|avif|svg|ico|css|js|woff2?)$ - [R=404,L]
</IfModule>
ErrorDocument 404 /errors/404.html
[R=404] のように300番台以外のステータスを指定すると、mod_rewriteは置換を行わず、そのステータスでリクエストを終えます。# BEGIN WordPress と # END WordPress の間は、パーマリンク設定の保存時にWordPressが書き直すため、独自のルールは枠の外に置くのがつまずかないコツです。
ただし、画像の拡大縮小やWebP変換を「アクセスされたときに生成する」タイプのプラグインやCDN連携を使っている場合、この設定で生成処理が動かなくなることがあります。導入前に、使っているプラグインが存在しない画像URLをWordPress経由で処理していないかを確認し、ステージング環境で画像の表示を一通り確かめてください。
PHP-FPMやリバースプロキシ構成での注意
ApacheからPHP-FPMやバックエンドのアプリにリクエストを渡す構成では、ProxyErrorOverride On を設定すると、バックエンドが返したエラー応答の中身をApacheのErrorDocumentで置き換えられます。
一見便利ですが、WordPressの場合はテーマの404ページやREST APIのエラー応答(JSON)まで差し替わってしまう恐れがあります。WordPressが404の画面を作れているなら、ProxyErrorOverride は既定のOffのままにしておくほうが無難です。バックエンドが停止して502や503になったときだけ独自ページを出したいなら、対象のステータスを限定する書き方ができるか、利用しているApacheのバージョンのドキュメントで確認してください。比較的新しい2.4系では、ProxyErrorOverride に対象のステータスコードを列挙できるようになっています(2026年10月現在)。
設定後の確認方法
見た目だけでなく、ステータスコードを確認するのが大切です。ブラウザで表示がそれらしく見えても、200や302で返っていることがあります。
# WordPressが返す404(テーマの404テンプレート)
curl -sI https://example.com/no-such-page/ | head -n 1
# Apacheが返す静的ファイルの404(ErrorDocument)
curl -sI https://example.com/wp-content/uploads/no-such-image.png | head -n 1
# 設定変更後の構文チェックと反映(VirtualHost を編集した場合)
sudo apachectl configtest && sudo systemctl reload apache2
どちらも HTTP/2 404 や HTTP/1.1 404 Not Found が返れば正しく動いています。302 や 200 が返る場合は、ErrorDocumentに外部URLを書いていないか、リダイレクト系のプラグインが404をトップページへ転送していないかを確認します。
うまくいかないときは、次の順で見ていくと原因にたどり着きやすくなります。
- 表示が変わらない: そのURLはWordPressが処理していないか(テーマの404が出ていないか)。
- .htaccessに書いても効かない:
AllowOverrideでFileInfoが許可されているか。エラーログに「not allowed here」がないか。 - 500エラーになった: .htaccess の綴りや引用符の閉じ忘れ。
/var/log/apache2/error.log(RHEL系は/var/log/httpd/error_log)の該当時刻の行を確認する。 - ステータスが302: ErrorDocumentの値が
https://から始まっていないか。
検索エンジンとの関係
削除したページが404(または410)を返すのは正常な状態で、それ自体がサイト全体の評価を下げるわけではない、というのがGoogle Search Centralの説明です。大切なのは、存在しないページに200を返さないことと、読者が次の行動に移れる404ページにすることです。サイト内検索のフォーム、トップページやカテゴリ一覧へのリンクを置くと、迷った読者を戻しやすくなります。
移転したページは404にせず、新しいURLへ301でリダイレクトします。逆に、関連の薄いトップページへ一括で301するのは、ソフト404として扱われやすいので避けます。
まとめ
- WordPressサイトの多くの404はテーマの404テンプレートが出している。デザイン変更はまずテーマ側で行う。
- ErrorDocumentはサイト内パス(
/errors/404.html)で指定する。外部URLにすると302になり、404として扱われない。 - エラーページのCSS・画像は
/から始まるパスで読み込み、どのURLでも崩れないようにする。 - 存在しない静的ファイルは
[R=404,L]でApacheに返させるとWordPressの無駄な起動を減らせる。独自ルールは# BEGIN WordPressの外に書き、画像生成系プラグインへの影響を確認する。 - 仕上げは
curl -sIでステータスコードを確認する。