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をトップページへ転送していないかを確認します。

うまくいかないときは、次の順で見ていくと原因にたどり着きやすくなります。

  1. 表示が変わらない: そのURLはWordPressが処理していないか(テーマの404が出ていないか)。
  2. .htaccessに書いても効かない: AllowOverride で FileInfo が許可されているか。エラーログに「not allowed here」がないか。
  3. 500エラーになった: .htaccess の綴りや引用符の閉じ忘れ。/var/log/apache2/error.log(RHEL系は /var/log/httpd/error_log)の該当時刻の行を確認する。
  4. ステータスが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 でステータスコードを確認する。

お気軽にご相談ください

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