2026年6月30日
2026年6月30日
WordPressの503 Service Unavailableを直す方法|原因の切り分けからPHP-FPM調整まで
WordPressの503エラーは、「どこが503を返しているか」を最初に特定すると、原因をかなり絞り込めます。メンテナンスモードの消し忘れ、PHP-FPMのプロセス不足、アクセス集中によるレート制限、レンタルサーバーのリソース制限が主な原因です。この記事を読むと、503を返している層を見分け、ログで原因を確かめ、再発しにくい設定に直すところまで進められます。
503が返る仕組みを先に押さえる
503 Service Unavailableは「サーバーは存在するが、今はリクエストを処理できない」という意味のステータスです。WordPressの構成では、次のどの層でも503が発生しえます。
- WordPress自身:更新中のメンテナンスモード、メンテナンス用プラグイン
- Webサーバー(Apache・Nginx):PHP-FPMにつながらない、レート制限に引っかかった
- CDN・WAF・ロードバランサー:オリジンサーバーが応答しない、または防御機能が遮断した
- レンタルサーバーの管理層:同時接続数やCPU使用量の上限を超えた
層によって対処がまったく違うため、いきなりPHPの設定を触るのではなく、まず発生源を確かめます。
手順1:どの層が503を返しているか確かめる
レスポンスヘッダーを見ると、応答している層の手がかりが得られます。
# ヘッダーだけ取得
curl -sI https://example.com/
# CDNを通さずオリジンへ直接(203.0.113.10 はオリジンのIPに置き換え)
curl -sI --resolve example.com:443:203.0.113.10 https://example.com/
確認する点は次のとおりです。
Server:ヘッダーや、CDN固有のヘッダー(キャッシュ状態を示すものなど)が付いているか- オリジンへ直接アクセスしたときも503になるか。直接なら正常に返るなら、CDNやWAF側の設定・障害を疑います
Retry-Afterヘッダーが付いているか。WordPressのメンテナンスモードやメンテナンス用プラグインは、これを付けて503を返すことが多いです
ページ本文も手がかりになります。WordPressのメンテナンスモードなら「現在メンテナンス中のため、しばらくの間ご利用いただけません」という趣旨の短い文だけが表示されます。レンタルサーバーの制限なら、事業者のロゴ入りのエラーページが出ることが多いです。
手順2:メンテナンスモードの消し忘れを確認する
WordPressはコア・プラグイン・テーマの更新中、ドキュメントルートに .maintenance というファイルを置き、その間は503を返します。更新が途中で止まると、このファイルが残ります。
ls -la /var/www/html/.maintenance
cat /var/www/html/.maintenance # 更新開始時刻(UNIX時刻)が書かれている
# 更新処理が動いていないことを確認してから削除
sudo rm /var/www/html/.maintenance
WordPressは .maintenance に書かれた時刻から10分以上経つと、ファイルが残っていてもメンテナンスモードを解除して表示を再開します。つまり、10分以上503が続くなら、.maintenance 以外の原因である可能性が高いと判断できます。
削除後は、途中で止まった更新を確認します。管理画面の「更新」画面でバージョン表示を見て、更新が完了していなければもう一度実行してください。プラグインのディレクトリが中途半端な状態で残っていると、今度は500エラーや白い画面になることがあります。
手順3:ログで原因を特定する
メンテナンスモードでなければ、ログを見ます。最初にアクセスログで、503がいつから、どのURLで、どのくらい出ているかを把握します。
# combined形式のログで、ステータス503の件数
awk '$9 == 503' /var/log/nginx/access.log | wc -l
# 503になったリクエストのURL上位
awk '$9 == 503 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# アクセス元IPの上位(503発生時間帯の集中を確認)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
wp-login.php や xmlrpc.php に特定のIPから大量のアクセスがあれば、ボットによる攻撃で処理能力が埋まっている可能性があります。admin-ajax.php への集中は、管理画面を開きっぱなしにしたことによるHeartbeat APIの通信や、特定プラグインの処理が原因のことがあります。
続いて、Webサーバーとphp-fpmのエラーログを確認します。
sudo tail -100 /var/log/nginx/error.log
sudo tail -100 /var/log/apache2/error.log
sudo journalctl -u php8.3-fpm --since "1 hour ago"
php-fpmのサービス名とログの場所はPHPのバージョンやディストリビューションで変わります(2026年10月現在、Debian/Ubuntuでは php8.3-fpm のような名前です)。systemctl list-units | grep fpm で実際の名前を確認してください。
ログに次のような行があれば、原因はほぼ特定できます。
- php-fpmの
server reached pm.max_children setting… PHPのプロセス数が上限に達している - Apacheの、FastCGIのバックエンドに接続できなかったというエラー … php-fpmが停止しているか、ソケットのパスが違う
- Nginxの
limiting requests…limit_reqによるレート制限が発動している
Nginxでは、php-fpmにつながらない場合はふつう502、応答が遅すぎる場合は504になります。Nginxが503を返すのは、limit_req や limit_conn の制限に引っかかったとき(既定の応答コードが503)が代表的です。一方、Apacheの mod_proxy_fcgi はバックエンドに接続できないと503を返します。同じ「PHPが応答しない」状態でも、Webサーバーによってステータスが違う点に注意してください。
手順4:PHP-FPMのプロセス数を見直す
pm.max_children の上限に達すると、新しいリクエストは空きを待つ列に並びます。列もあふれると、接続が拒否されたりタイムアウトしたりして、503や502、504になります。
ただし、上限を大きくすればよいわけではありません。メモリに収まらない数にすると、スワップの多用やOOM Killerによるプロセスの強制終了が起き、状況が悪化します。1プロセスあたりのメモリ使用量から上限を計算します。
# php-fpm workerの平均メモリ使用量(MB)
ps --no-headers -o rss -C php-fpm8.3 | awk '{s+=$1; n++} END {printf "%.1f MB x %d procs\n", s/n/1024, n}'
# サーバー全体のメモリ
free -m
たとえば、PHPに回せるメモリが2,000MBで、1プロセスが平均80MBなら、上限は25前後が目安です。MySQLやWebサーバーが使う分は先に差し引いてください。
; /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
; 同時に動かせるPHPプロセスの上限(2000MB ÷ 80MB ≒ 25)
pm.max_children = 25
; 起動時のプロセス数
pm.start_servers = 6
; 待機プロセスの最小数と最大数
pm.min_spare_servers = 4
pm.max_spare_servers = 10
; 1プロセスが500リクエスト処理したら作り直す(メモリリーク対策)
pm.max_requests = 500
pm = dynamic では、pm.start_servers を pm.min_spare_servers 以上 pm.max_spare_servers 以下にしないと、php-fpmが起動しません。変更前に設定ファイルをコピーしておき、構文を確認してから反映します。
sudo cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/www.conf.bak
sudo php-fpm8.3 -t # 設定の構文チェック
sudo systemctl reload php8.3-fpm
プロセス数を増やす前に、1リクエストの処理時間を短くできないかも検討してください。ページキャッシュを導入すると、PHPを通らずに返せるリクエストが増え、同じプロセス数でもはるかに多くのアクセスをさばけます。
手順5:アクセス集中とボットへの対処
ログで特定のIPやURLへの集中が見つかった場合は、PHPに届く前に止めるのが効果的です。
- 使っていなければ
xmlrpc.phpへのアクセスをWebサーバー側で拒否する wp-login.phpに対して、WAFやWebサーバーのレート制限をかける- 攻撃元のIPを一時的にファイアウォールで遮断する
逆に、Nginxの limit_req を厳しくしすぎたことが503の原因になっている場合もあります。画像やCSSが多いページでは、1回のページ表示で数十のリクエストが発生します。制限を静的ファイルにまでかけていないか、burst の値が小さすぎないかを確認してください。
レンタルサーバーの場合
共用のレンタルサーバーでは、php-fpmの設定を自分で変えられません。多くの事業者は、同時接続数やCPU使用時間などに上限を設けていて、超えると503や独自のエラーページを返します。
- サーバーのコントロールパネルで、リソース使用状況やエラーログを確認する
- キャッシュ系のプラグインやサーバー側のキャッシュ機能を有効にして、PHPの処理回数を減らす
- 重い処理をするプラグイン(関連記事の生成、アクセス解析、バックアップなど)を一時的に止めて変化を見る
- 恒常的に上限に届くなら、上位プランやVPSへの移行を検討する
SEOへの影響と、計画的な503
短時間の503は、検索エンジンに「一時的な停止」として扱われます。計画メンテナンスでは、むしろ200でメンテナンス画面を返すより、Retry-After を付けた503を返すほうが適切です。ただし、503が長期間続くと、検索結果から外れるおそれがあります。原因の特定に時間がかかる場合でも、まずキャッシュの有効化や不要なアクセスの遮断で、表示できる状態に戻すことを優先してください。
まとめ
- 503は複数の層で発生する。最初に
curl -sIとオリジンへの直接アクセスで、どの層が返しているかを確かめる .maintenanceは10分経つと無視されるため、それ以上続く503は別の原因を疑う- アクセスログで503の件数・URL・アクセス元を集計し、エラーログで
pm.max_childrenやレート制限のメッセージを探す - Nginxは接続失敗で502、Apacheは503を返すなど、Webサーバーによってステータスが異なる
pm.max_childrenは、PHPに回せるメモリを1プロセスの平均使用量で割って決める。変更前にバックアップと構文チェックを行う- ボットの集中はPHPに届く前に止め、ページキャッシュで処理回数そのものを減らす