- SEO
503とSEO|500との違い・Googleの扱いとメンテナンス時の正しい返し方
結論
500と503は HTTP の意味が違いますが、Google 検索の公式ページではどちらも「サーバーエラー」として同じ行に並び、クロールが一時的に減り、同じ URL で続けばインデックスから外れます。計画したメンテナンスは数時間〜1〜2日なら 503+Retry-After で返し、robots.txt は 200 のままにするのが Google の案内に沿った形です。
この記事でわかること
- Google 公式に書かれた5xx・429・Retry-After・robots.txt の扱い
- nginx・Apache・WordPress 相当・Python で503を返した curl -I の実物
- 200のメンテナンス画面・robots.txt まで503・キャッシュ残りの再現と判断表
サイトを止めるとき、検索への影響を左右するのは「何秒止めたか」よりも「止めている間に何を返したか」です。同じメンテナンス画面でも、200で返すか503で返すか、robots.txt をどう返すかで、Google の受け取り方が変わります。まず、止める長さで返すものを選びます。
flowchart TD
S[サイトを止めたい] --> Q1{止めるのは<br>1〜2日以内?}
Q1 -->|はい| A[503+Retry-After<br>robots.txtは200]
Q1 -->|いいえ| Q2{再開する<br>予定がある?}
Q2 -->|はい| B[200の告知<br>機能だけ止める]
Q2 -->|いいえ| C[やめるなら<br>404・410]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| 500と503の違い | 500は予期しない故障、503は一時的に処理できない状態。Google の表では同じ行に並ぶ | 500と503の違い |
| 503はSEOに影響する? | 短時間ならクロールが一時的に減る。同じ URL で数日続くとインデックスから外れることがある | Googleは500・503をどう扱うか |
| メンテナンスの503は何日まで? | 公式の目安は数時間〜1〜2日。それより長いなら200の告知ページ | 503は何日まで |
| Retry-After は付ける? | 503・429に付けられる(秒数か UTC の日時)と公式が案内している | Retry-Afterヘッダー |
| robots.txt も503にする? | しない。5xxだと最初の12時間はサイト全体のクロールが止まる | robots.txtが5xxを返したとき |
| メンテナンス画面を200で返すと? | 画面の文章がページの中身として扱われ、ソフト404になり得る | よくある失敗の再現 |
| 429はどう扱われる? | 過負荷の合図として、サーバーエラーと同じ扱い | Googleは500・503をどう扱うか |
| CDN にメンテナンス画面が残る | 200で返した画面はキャッシュされる。503は Cache-Control: no-store を付ける | キャッシュに残る失敗 |
| どのコードを返すか迷う | 止める長さ・再開の予定・原因で決める | 判断表 |
確認環境:Ubuntu 24.04.5 LTS の上で、Ubuntu の nginx 1.24.0 と Apache 2.4.58 の .deb を作業用のフォルダーに展開し(ホストには入れていません)、自分の設定ファイルで 127.0.0.1 のポートに起動して、メンテナンス時に503+Retry-After を返す設定と、よくある失敗の設定を動かしました。WordPress は本体を入れず、WordPress の公式リファレンスに載っている wp_maintenance()・wp_is_maintenance_mode() と同じ順番で判定する PHP を PHP 8.3.6 の内蔵サーバーで動かしています。Python 3.13.18 の標準ライブラリで Retry-After を日付で返すサーバーを作り、その手前に nginx の proxy_cache を CDN の代わりに置いて、キャッシュに残る失敗を再現しました。応答はすべて curl 8.5.0 の curl -I と -w で取っています。Googlebot の挙動そのものは手元で確かめられないため、Google 検索セントラルの公式ページ(HTTP ステータスコードとネットワークエラー、クロール頻度を下げる、robots.txt の仕様、ウェブサイトを一時停止または無効化する)と Search Console ヘルプの記述の範囲で書いています。ヘッダーの定義は MDN、設定の仕様は nginx・Apache の公式ドキュメントで確かめました。図は mermaid 11.16.0 で描画を確かめています(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「503とSEO|500との違い・Googleの扱いとメンテナンス時の正しい返し方」
500と503の違い(HTTPの意味とGoogle検索での扱い)
この節では、500と503が HTTP として何を意味し、Google 検索の公式ページでどう並んでいるかが分かります。
500 Internal Server Error は「サーバーの中で想定外のことが起きた」、503 Service Unavailable は「今は一時的に処理できない」という意味です。 MDN は503について、よくある原因はメンテナンスか過負荷で、一時的な状況に使い、できれば Retry-After ヘッダーで復旧までの見込み時間を伝えるべきだ、と説明しています。
| 500 Internal Server Error | 503 Service Unavailable | |
|---|---|---|
| 意味 | 想定外の故障。どこが悪いかを伝えない | 一時的に処理できない(メンテナンス・過負荷) |
| 返し方 | 多くはプログラムの例外や設定の誤りで「返ってしまう」 | メンテナンスや混雑時に「意図して返す」ことが多い |
| Retry-After | 付けない(いつ直るか分からない) | 付けられる。秒数か日時 |
| Google の表(ステータスコードの影響) | 500・502・503が同じ行。クロール頻度が下がり、繰り返すとインデックスから削除 | 同上 |
| Google の「クロール頻度を下げる」 | 500・503・429のどれでも、短期間ならクロールを減らせる | 同上。503と429には Retry-After を付けられる |
| 手元で返した例 | PHP の未定義関数の呼び出しで HTTP/1.0 500 Internal Server Error |
nginx の return 503 で HTTP/1.1 503 Service Temporarily Unavailable |
500(故障が起きた)
原因を直すまで続く
利用者には「何が起きたか」が伝わらない
意図して返すものではなく、直す対象
503(今だけ止めている)
メンテナンス・過負荷で一時的
Retry-After で再開の目安を伝えられる
止める側が設定で選んで返せる
検索への影響で言えば、公式ページに「500より503のほうが順位に有利」といった記述はありません。 Google 検索セントラルの「HTTP ステータスコード、ネットワーク エラー、DNS エラーが Google 検索に与える影響」は、500・502・503を1つの行にまとめて同じ説明を書いています。違いが出るのは、503は止める側が意図して返せること、Retry-After を付けられること、人にも「一時的」と伝えられることです。この記事では、公式に書かれていない順位の差は扱いません。
500が出たときの原因の探し方と直し方は、関連記事「500エラーとは|Internal Server Errorの原因と直し方を実例で」で扱っています。ステータスコード全体の一覧は、関連記事「HTTPステータスコード 一覧|全コードの原因と対処・curl実例つき」で扱っています。
Googleは500・503をどう扱うか(公式の記述)
この節では、5xx と429を返したときに Google のクロールとインデックスがどう動くかが、公式の文言で分かります。
5xx と429は「クロールの速さを落とす合図」として扱われ、続くとインデックスから外れます。 公式ページ(日本語版)の記述を、そのまま引きます。
- 「5xx および 429 のサーバーエラーは、Google のクローラに対して一時的にクロールのペースを落とすように促します。」
- 「サーバーが 2xx ステータス コードを返すようになると、Google はサイトのクロール頻度を徐々に引き上げます。」
- 500(502・503と同じ行):「Google はサイトのクロール頻度を落とします。」「クロール頻度の低下は、サーバーエラーを返す個別の URL の数に比例します。」「Google 検索の場合、Google のインデックス登録パイプラインは、繰り返してサーバーエラーを返す URL をインデックスから削除します。」
- 429:「Google のクローラーは、429 ステータス コードをサーバーが過負荷状態であることを示すシグナルとして扱います。」「これはサーバーエラーとみなされます。」
英語版には、5xx について「すでにインデックスにある URL は保たれるが、最終的には削除される」「5xx を返す URL から受け取った中身はすべて無視される」という説明もあります。
1クロールが遅くなる
5xx・429を受けると、Google はクロールのペースを落とす。下がり方はエラーを返す URL の数に比例する。
2中身は使われない
5xx で返したメンテナンス画面の文章は無視される。200で返すと、その文章がページの中身として扱われる。
3続くと削除される
繰り返してエラーを返す URL はインデックスから削除される。短時間なら、すでに登録された URL は保たれる。
4戻れば徐々に回復
2xx に戻ると、クロール頻度は自動で徐々に上がる。一度に元へ戻るわけではない。
ほかのコードとの違いを、同じページの記述から表にします。
| 返したもの | クロール | インデックス・中身 |
|---|---|---|
| 2xx | 次の処理へ進む | 中身を使う。ただし登録は保証されない。エラーのような中身ならソフト404 |
| 3xx | 既定で10回までリダイレクトをたどる | 301は転送先を使う強い合図、302は弱い合図 |
| 4xx(429以外) | 過負荷の合図としては扱わない(クロール制限に401・403を使わない) | 中身を使わず、登録済みの URL も削除される |
| 429 | 過負荷の合図。ペースを落とす | サーバーエラーと同じ扱い |
| 500・502・503 | ペースを落とす(URL の数に比例) | 中身は無視。繰り返すと削除 |
502・504はサーバーの手前の中継で起きることが多く、原因の切り分けは関連記事「504 Gateway Time-outとは?原因と直し方|見ている人・運営者別」で扱っています。
メンテナンスの503は何日まで(数時間〜1〜2日の目安)
この節では、503で止めてよい長さの目安と、それを超えるときの公式の案内が分かります。
公式の目安は「数時間、または1〜2日」です。 「クロール頻度を下げる」のページは、緊急にクロールを減らす方法として、短い期間だけ200の代わりに500・503・429を返すことを挙げ、1〜2日を超える期間には勧めていません。同じ URL で数日にわたってこれらのコードが返ると、インデックスから削除される場合がある、とも書いています。
サイトを止める場面そのものは、「ウェブサイトを一時停止または無効化する」のページが扱っています。こちらの要点は次のとおりです。
| 止め方・長さ | 公式の案内 | 出典のページ |
|---|---|---|
| 数時間〜1〜2日(緊急) | 200の代わりに500・503・429。1〜2日を超えて使わない | クロール頻度を下げる |
| 緊急に1〜2日だけ止める | 503のエラーページを返す。retry-after で再開の目安を伝え、ページに再開予定と問い合わせ先を書く | 一時停止または無効化する |
| 1日より長く止める | 200で、インデックスに登録できる告知のホームページを出す | 一時停止または無効化する |
| サイト全体の無効化 | 最終手段。長くても2〜3日程度にとどめる | 一時停止または無効化する |
| 再開の見込みがある一時停止 | サイトは公開したまま、カートなどの機能だけ止めるのが勧められている | 一時停止または無効化する |
同じページは、503を返している間はページのタイトルや構造化データなどが更新されないこと、robots.txt では503を返さずクロールを許可したままにすること、403・404・410を返す・noindex を付ける・一時的な削除ツールを使う方法はサイトが検索から消えるため避けることも書いています。
「クロール頻度を下げる」のページは影響の範囲にも触れています。クロールが減るのはホスト名全体で、新しいページの発見や既存ページの更新(価格や在庫など)の反映が遅れ、削除したページがインデックスに残る期間も長くなることがあります。Google 広告のキャンペーンが止まることもある、と書かれています。
Retry-Afterヘッダーの書き方(秒数とHTTP日付)
この節では、Retry-After の2つの書き方と、Google が Retry-After について書いている範囲が分かります。
Retry-After は「秒数」か「HTTP 日付」で書きます。 MDN の構文は Retry-After: <http-date> と Retry-After: <delay-seconds> の2つで、503なら「サービスが利用できないと予想される期間」、429なら「新しいリクエストを行うまでの待ち時間」を表します。
Retry-After: 3600
Retry-After: Thu, 29 Oct 2026 14:00:00 GMT
Google の記述は、「クロール頻度を下げる」のページにある「503 または 429 とともに Retry-After ヘッダーを付けると、再試行までの遅延を秒数で、または絶対 UTC 日時で指定できる」という趣旨の説明です。「HTTP ステータスコード…」のページには Retry-After の記述はありません。Googlebot が値をどう使い、何秒後に必ず来るのかは公式に書かれていないため、この記事では断定しません。人が読むメンテナンス画面と同じく、再開の目安を機械にも伝える目的で付けます。
HTTP 日付は GMT で書きます。日本時間 23:00 に再開する予定なら、次のように作れます。
$ date -u -d '2026-10-29 23:00 JST' '+%a, %d %b %Y %H:%M:%S GMT'
Thu, 29 Oct 2026 14:00:00 GMT
$ python3 -c "from email.utils import format_datetime;import datetime as d;print(format_datetime(d.datetime(2026,10,29,14,tzinfo=d.timezone.utc),usegmt=True))"
Thu, 29 Oct 2026 14:00:00 GMT
| 書き方 | 向いている場面 | 気をつけること |
|---|---|---|
| 秒数(3600 など) | 終わりが読めない作業・過負荷 | 設定に固定で書ける。WordPress の既定は600 |
| HTTP 日付(GMT) | 終了時刻が決まった計画メンテナンス | 延長したら書き換える。過去の日付が残ると意味を持たない |
nginx の add_header と Apache の Header は、書き方によっては503に付きません。次の節の設定で、付く書き方と付かない書き方の両方を動かしています。
robots.txtが5xxを返したとき(12時間・30日の流れ)
この節では、メンテナンスで robots.txt まで503にしたときに何が起きるかが、公式の仕様で分かります。
robots.txt が5xxを返すと、最初の12時間はサイト全体のクロールが止まります。 ページを503にするのとは影響の大きさが違います。robots.txt の仕様(日本語版)の記述を、経過の順に表にします。
| robots.txt の応答 | Google の動き |
|---|---|
| 2xx | 返された内容のとおりに処理する |
| 3xx | 5回を超えるリダイレクトなどは404として扱う |
| 4xx(429以外) | robots.txt が無いものとみなし、制限なしでクロールする |
| 5xx(最初の12時間) | サイトのクロールを止め、robots.txt の取得は続ける |
| 5xx(その後30日まで) | 前回取得できた版を使う。前の版が無ければ制限なしとみなす |
| 5xx(30日を過ぎても続く) | サイトが公開されていれば robots.txt が無いものとして扱い、そうでなければクロールを止める。取得は定期的に続ける |
| DNS・タイムアウトなど | サーバーエラーとして扱う |
429は、Search Console ヘルプの「クロールの統計情報レポート」で5xxと同じ「不成功な応答」に入っています。robots.txt は通常最大24時間キャッシュされ、更新できないとき(タイムアウトや5xx)はさらに長く保たれること、Cache-Control の max-age で期間が延びたり縮んだりすることも仕様に書かれています。
メンテナンス中も robots.txt は200で返し、Disallow: / に書き換えないことが大切です。一時停止のページは、robots.txt で全体のクロールを禁止するとコンテンツや URL が検索から削除されるおそれがある、と書いています。robots.txt そのものの書き方は、関連記事「robots.txt・sitemap.xmlの書き方|テンプレートと検証手順」で扱っています。
nginxでメンテナンス時に503+Retry-Afterを返す(設定全文)
この節では、nginx でファイル1つを置くだけでメンテナンスに切り替わる設定と、その curl -I の実物が分かります。
「maintenance.on が置かれていれば503、robots.txt は200のまま、社内の端末は素通り」という形にしました。 作業の順番は次のとおりです。
メンテナンス画面を用意する
再開の予定日時と問い合わせ先を書いた maintenance.html を置く。画像や CSS を別ファイルにすると、それも503になるので1枚に収める。
設定を書いて文法を確かめる
下の設定を入れ、nginx -t で文法を確かめてから再読み込みする。
印のファイルを置く
touch maintenance.on でメンテナンスに入る。設定の再読み込みは要らない。
外から応答を確かめる
ページが503と Retry-After、robots.txt が200になっているかを curl -I で見る。
終わったら印を消す
rm maintenance.on で戻し、200に戻ったことと、CDN のキャッシュが残っていないことを確かめる。
確かめた設定ファイルの全文です。正しい例(18240番)のほか、後の節で使う失敗例とキャッシュの再現も同じファイルに入れています。
# /dev/shm/t240/nginx/nginx.conf(確認用。127.0.0.1 だけで待ち受け)
worker_processes 1;
pid /dev/shm/t240/nginx/nginx.pid;
error_log /dev/shm/t240/nginx/logs/error.log warn;
events { worker_connections 64; }
http {
include /srv/s4/r17/t240/root/etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/shm/t240/nginx/logs/access.log;
client_body_temp_path /dev/shm/t240/nginx/tmp/body;
proxy_temp_path /dev/shm/t240/nginx/tmp/proxy;
fastcgi_temp_path /dev/shm/t240/nginx/tmp/fcgi;
uwsgi_temp_path /dev/shm/t240/nginx/tmp/uwsgi;
scgi_temp_path /dev/shm/t240/nginx/tmp/scgi;
server_tokens off;
# 社内から確認する端末だけメンテナンスを素通りさせる
geo $maint_bypass {
default 0;
127.0.0.2 1;
}
# ---- 正しい例:503 + Retry-After、robots.txt は 200 のまま ----
server {
listen 127.0.0.1:18240;
root /dev/shm/t240/nginx/html;
set $maint 0;
if (-f $document_root/maintenance.on) { set $maint 1; }
if ($maint_bypass) { set $maint 0; }
error_page 503 /maintenance.html;
location = /maintenance.html {
internal;
add_header Retry-After 3600 always;
add_header Cache-Control "no-store" always;
}
location = /robots.txt {
try_files $uri =404;
}
location / {
if ($maint) { return 503; }
try_files $uri $uri/ =404;
}
}
# ---- 失敗例1:メンテナンス画面を 200 で返す ----
server {
listen 127.0.0.1:18241;
root /dev/shm/t240/nginx/html;
location / {
try_files /maintenance.html =404;
}
}
# ---- 失敗例2:robots.txt まで 503、Retry-After に always がない ----
server {
listen 127.0.0.1:18242;
root /dev/shm/t240/nginx/html;
error_page 503 /maintenance.html;
add_header Retry-After 3600;
location = /maintenance.html { internal; }
location / { return 503; }
}
# ---- キャッシュ(CDN の代わり):200 だけ10分キャッシュ ----
proxy_cache_path /dev/shm/t240/nginx/cache/a keys_zone=ca:1m max_size=10m;
proxy_cache_path /dev/shm/t240/nginx/cache/b keys_zone=cb:1m max_size=10m;
server {
listen 127.0.0.1:18243;
location / {
proxy_pass http://127.0.0.1:18244;
proxy_cache ca;
proxy_cache_valid 200 10m;
add_header X-Cache-Status $upstream_cache_status always;
}
}
# ---- キャッシュ:どのコードも1分キャッシュ(503 も残る)----
server {
listen 127.0.0.1:18245;
location / {
proxy_pass http://127.0.0.1:18244;
proxy_cache cb;
proxy_cache_valid any 1m;
add_header X-Cache-Status $upstream_cache_status always;
}
}
}
メンテナンス画面(maintenance.html)は次の1枚です。
<!doctype html>
<html lang="ja">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>メンテナンス中</title></head>
<body>
<h1>ただいまメンテナンス中です</h1>
<p>2026年10月29日 22:00〜23:00(日本時間)の予定です。終わりしだい再開します。</p>
<p>お急ぎの方は お問い合わせ窓口(電話・メール)へご連絡ください。</p>
</body>
</html>
通常時と、maintenance.on を置いた後の応答です。
$ curl -sS -I http://127.0.0.1:18240/
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 01 Nov 2026 06:18:55 GMT
Content-Type: text/html
Content-Length: 112
Last-Modified: Sun, 01 Nov 2026 06:18:37 GMT
Connection: keep-alive
ETag: "6ae6d9bd-70"
Accept-Ranges: bytes
$ touch /dev/shm/t240/nginx/html/maintenance.on
$ curl -sS -I http://127.0.0.1:18240/
HTTP/1.1 503 Service Temporarily Unavailable
Server: nginx
Date: Sun, 01 Nov 2026 06:18:55 GMT
Content-Type: text/html
Content-Length: 458
Connection: keep-alive
ETag: "6ae6d9bd-1ca"
Retry-After: 3600
Cache-Control: no-store
$ curl -sS -I http://127.0.0.1:18240/robots.txt
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/plain
Content-Length: 67
$ curl -sS -I --interface 127.0.0.2 http://127.0.0.1:18240/
HTTP/1.1 200 OK
読み取れることは4つです。
- nginx の503の理由句は「Service Temporarily Unavailable」でした。状態コードは503なので、扱いは同じです。
- Retry-After と Cache-Control には
alwaysを付けています。 nginx の公式ドキュメントは、add_headerが付くのは200・201・204・206・301・302・303・304・307・308のときだけで、alwaysを付けると状態コードに関係なく付く、と説明しています。 - robots.txt は別の location にして、503の判定を通らないようにしています。
- geo で 127.0.0.2 からの接続だけ素通りにし、作業する人は通常の画面で確かめられます。実際の環境では、ここに社内の固定 IP を書きます。
maintenance.html を internal にしているため、この URL を直接開くと404になります(その404にも Retry-After が付きましたが、検索に出す URL ではないので害はありません)。nginx の location の優先順位やリバースプロキシの設定は、関連記事「Nginxリバースプロキシ設定|proxy_passの書き方と502/504対処」で扱っています。
Apacheで503を返す(httpd.confと.htaccess)
この節では、Apache で同じ切り替えを mod_rewrite と mod_headers で書いた全文と、always の有無で何が変わったかが分かります。
Apache は RewriteRule ^ - [R=503,L] で503を返し、ErrorDocument 503 でメンテナンス画面を出し、Header always set で Retry-After を付けます。 確かめた設定ファイルの全文です。
# /dev/shm/t240/apache/httpd.conf(確認用。127.0.0.1 だけで待ち受け)
ServerRoot "/srv/s4/r17/t240/root/usr/lib/apache2"
PidFile "/dev/shm/t240/apache/run/httpd.pid"
DefaultRuntimeDir "/dev/shm/t240/apache/run"
ErrorLog "/dev/shm/t240/apache/logs/error.log"
LogLevel warn
ServerName 127.0.0.1
ServerTokens Prod
Listen 127.0.0.1:18247
Listen 127.0.0.1:18248
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule mime_module modules/mod_mime.so
LoadModule dir_module modules/mod_dir.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
TypesConfig "/etc/mime.types"
AddDefaultCharset utf-8
DirectoryIndex index.html
DocumentRoot "/dev/shm/t240/apache/html"
<Directory "/dev/shm/t240/apache/html">
Require all granted
AllowOverride None
</Directory>
# ---- 正しい例:maintenance.on があれば 503 + Retry-After ----
<VirtualHost 127.0.0.1:18247>
ErrorDocument 503 /maintenance.html
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/maintenance.on -f
RewriteCond %{REMOTE_ADDR} !=127.0.0.2
RewriteCond %{REQUEST_URI} !=/robots.txt
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^ - [R=503,L]
Header always set Retry-After "3600" "expr=%{REQUEST_STATUS} == 503"
Header always set Cache-Control "no-store" "expr=%{REQUEST_STATUS} == 503"
</VirtualHost>
# ---- 失敗例:always がない Header set ----
<VirtualHost 127.0.0.1:18248>
ErrorDocument 503 /maintenance.html
RewriteEngine On
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^ - [R=503,L]
Header set Retry-After "3600"
</VirtualHost>
# ---- 確認用:ErrorDocument なし + always なし ----
Listen 127.0.0.1:18249
<VirtualHost 127.0.0.1:18249>
RewriteEngine On
RewriteRule ^ - [R=503,L]
Header set Retry-After "3600"
</VirtualHost>
# ---- 確認用:.htaccess で同じことをする ----
Listen 127.0.0.1:18250
<VirtualHost 127.0.0.1:18250>
DocumentRoot "/dev/shm/t240/apache/ht"
<Directory "/dev/shm/t240/apache/ht">
Require all granted
AllowOverride FileInfo
</Directory>
</VirtualHost>
# ---- 失敗例:302 でメンテナンス画面へ飛ばす ----
Listen 127.0.0.1:18251
<VirtualHost 127.0.0.1:18251>
RewriteEngine On
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^ /maintenance.html [R=302,L]
</VirtualHost>
$ curl -sS -I http://127.0.0.1:18247/ # maintenance.on を置いた後
HTTP/1.1 503 Service Unavailable
Date: Sun, 01 Nov 2026 06:20:41 GMT
Server: Apache
Retry-After: 3600
Cache-Control: no-store
Last-Modified: Sun, 01 Nov 2026 06:20:29 GMT
ETag: "1ca-65f3106a60624"
Accept-Ranges: bytes
Content-Length: 458
Connection: close
Content-Type: text/html; charset=utf-8
$ curl -sS -I http://127.0.0.1:18247/robots.txt
HTTP/1.1 200 OK
$ curl -sS -I --interface 127.0.0.2 http://127.0.0.1:18247/
HTTP/1.1 200 OK
$ curl -sS -I http://127.0.0.1:18249/ # ErrorDocument なし・always なし
HTTP/1.1 503 Service Unavailable
Date: Sun, 01 Nov 2026 06:20:48 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=iso-8859-1
always の無い Header set は、ErrorDocument を置いていない18249番では Retry-After が付きませんでした。 ErrorDocument でローカルのページを出す18248番では付きましたが、Apache の公式ドキュメントは、always の表のヘッダーは「エラーのときにも付き、ErrorDocument などの内部リダイレクトをまたいで保たれる」と説明しています。設定の組み合わせで結果が変わるのを避けるため、503に付けるヘッダーは always で書きます。ErrorDocument が無いと、Apache の既定の英語のページ(charset=iso-8859-1)が出る点も分かります。
共用サーバーなどで httpd.conf を触れない場合は、同じ内容を .htaccess に書けます(AllowOverride で FileInfo が許可されていることが前提です)。
# .htaccess(AllowOverride FileInfo が必要。mod_rewrite・mod_headers を使う)
ErrorDocument 503 /maintenance.html
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/maintenance.on -f
RewriteCond %{REMOTE_ADDR} !=127.0.0.2
RewriteCond %{REQUEST_URI} !=/robots.txt
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^ - [R=503,L]
Header always set Retry-After "3600" "expr=%{REQUEST_STATUS} == 503"
$ curl -sS -I http://127.0.0.1:18250/
HTTP/1.1 503 Service Unavailable
Server: Apache
Retry-After: 3600
Content-Length: 458
Content-Type: text/html; charset=utf-8
$ curl -sS -I http://127.0.0.1:18250/robots.txt
HTTP/1.1 200 OK
.htaccess のほかの書き方(リダイレクトや https 化)は、関連記事「.htaccessの書き方|リダイレクト・https化・アクセス制限のコピペ集」で扱っています。
WordPressのメンテナンスモードと503(.maintenanceとmaintenance.php)
この節では、WordPress の更新中に出る「Briefly unavailable for scheduled maintenance」が何を返しているかと、自作のメンテナンス画面で200になってしまう落とし穴が分かります。
WordPress 本体は、メンテナンス中に503と Retry-After: 600 を返します。 公式リファレンスに載っている wp_maintenance() は、メンテナンス中なら header( 'Retry-After: 600' ); を送り、wp_die( …, 503 ) で終わります。メンテナンス中かどうかは wp_is_maintenance_mode() が決め、サイトの直下に .maintenance があり、その中の $upgrading(時刻)から10分たっていなければメンテナンス中と判定します。
落とし穴は wp-content/maintenance.php(ドロップイン)です。 このファイルがあると、本体はそれを読み込んで die() するだけで、状態コードも Retry-After も送りません。画面だけ作ると200になります。本体を入れずに、同じ順番で判定する PHP を作って確かめました。
<?php
// index.php:WordPress の wp_maintenance() と同じ順番で判定する再現(本体は入れていない)
define('ABSPATH', __DIR__ . '/');
define('WP_CONTENT_DIR', __DIR__ . '/wp-content');
function wp_is_maintenance_mode() {
global $upgrading;
if (!file_exists(ABSPATH . '.maintenance')) return false;
require ABSPATH . '.maintenance'; // $upgrading = time(); が書かれている
if ((time() - $upgrading) >= 10 * 60) return false; // 10分を過ぎたら解除扱い
return true;
}
function wp_maintenance() {
if (!wp_is_maintenance_mode()) return;
if (file_exists(WP_CONTENT_DIR . '/maintenance.php')) { // ドロップインがあれば任せる
require_once WP_CONTENT_DIR . '/maintenance.php';
die();
}
header('Retry-After: 600');
http_response_code(503);
echo "Briefly unavailable for scheduled maintenance. Check back in a minute.";
die();
}
if (($_SERVER['REQUEST_URI'] ?? '') === '/boom') {
undefined_function_call(); // 500 を起こすための呼び出し
}
wp_maintenance();
echo "<!doctype html><title>トップ</title><h1>通常のページ</h1>";
正しいドロップインは、状態コードとヘッダーを自分で出します。
<?php
// wp-content/maintenance.php(正しい例):状態コードとヘッダーを自分で出す
http_response_code(503);
header('Retry-After: 3600');
header('Cache-Control: no-store');
header('Content-Type: text/html; charset=utf-8');
?>
<!doctype html><html lang="ja"><meta charset="utf-8"><title>メンテナンス中</title>
<h1>ただいまメンテナンス中です</h1><p>23:00(日本時間)に再開する予定です。</p></html>
状態コードを出さない失敗例です。
<?php
// wp-content/maintenance.php(失敗例):画面だけ作って状態コードを出していない
?>
<!doctype html><html lang="ja"><meta charset="utf-8"><title>メンテナンス中</title>
<h1>ただいまメンテナンス中です</h1></html>
4つの場合の応答です。
$ echo '<?php $upgrading = 1793514068; ?>' > site/.maintenance
# ドロップインなし(本体の既定の動き)
$ curl -sS -I http://127.0.0.1:18246/
HTTP/1.1 503 Service Unavailable
X-Powered-By: PHP/8.3.6
Retry-After: 600
Content-type: text/html; charset=UTF-8
# 状態コードを出さないドロップイン
$ curl -sS -I http://127.0.0.1:18246/
HTTP/1.1 200 OK
X-Powered-By: PHP/8.3.6
Content-type: text/html; charset=UTF-8
# 正しいドロップイン
$ curl -sS -I http://127.0.0.1:18246/
HTTP/1.1 503 Service Unavailable
X-Powered-By: PHP/8.3.6
Retry-After: 3600
Cache-Control: no-store
Content-Type: text/html; charset=utf-8
# .maintenance の時刻が11分前(10分を過ぎた)
$ curl -sS -I http://127.0.0.1:18246/
HTTP/1.1 200 OK
| 状態 | 応答 | 読み取れること |
|---|---|---|
| .maintenance あり・ドロップインなし | 503、Retry-After: 600 | 本体の既定は SEO の面でも問題のない形 |
| ドロップインで画面だけ作った | 200 | メンテナンス画面がページの中身として扱われ得る |
| ドロップインで状態コードも出した | 503、Retry-After: 3600 | 自作の画面でも503を保てる |
| .maintenance が10分より前の時刻 | 200(通常の処理へ進む) | 更新が途中で止まって .maintenance が残っても、10分で判定が外れる |
メンテナンス用のプラグインを使う場合も、状態コードはプラグインの作りしだいです。入れたら一度 curl -I で503になっているかを見ます。
Python(標準ライブラリ)でRetry-Afterを日付で返す
この節では、フレームワークを使わずに、503と Retry-After(HTTP 日付)を返すサーバーの全文と応答が分かります。
Retry-After の HTTP 日付は email.utils.format_datetime(…, usegmt=True) で作れます。 mode ファイルの中身で、通常・503・Cache-Control なしの503・200のメンテナンス画面を切り替えるようにしました。最後の2つは、次の節以降の失敗の再現に使います。
# maint_server.py:標準ライブラリだけのメンテナンス切り替えサーバー(127.0.0.1:18244)
# mode ファイルの中身で動きを変える:normal / maint503 / maint503nc / maint200
import pathlib, datetime
from email.utils import format_datetime
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
BASE = pathlib.Path(__file__).parent
MODE_FILE = BASE / "mode"
# 再開予定(UTC)。Retry-After は HTTP 日付でも秒数でもよい
REOPEN = datetime.datetime(2026, 10, 29, 14, 0, 0, tzinfo=datetime.timezone.utc)
MAINT_HTML = """<!doctype html><html lang="ja"><meta charset="utf-8">
<title>メンテナンス中</title><h1>ただいまメンテナンス中です</h1>
<p>23:00(日本時間)に再開する予定です。</p></html>""".encode()
NORMAL_HTML = """<!doctype html><html lang="ja"><meta charset="utf-8">
<title>トップ</title><h1>通常のページ</h1></html>""".encode()
ROBOTS = b"User-agent: *\nAllow: /\n"
class H(BaseHTTPRequestHandler):
server_version = "maint/1.0"
def _send(self, code, body, ctype, extra=None):
self.send_response(code)
self.send_header("Content-Type", ctype)
self.send_header("Content-Length", str(len(body)))
for k, v in (extra or {}).items():
self.send_header(k, v)
self.end_headers()
if self.command != "HEAD":
self.wfile.write(body)
def do_GET(self):
mode = MODE_FILE.read_text().strip() if MODE_FILE.exists() else "normal"
if self.path == "/robots.txt": # robots.txt はメンテナンス中も 200
return self._send(200, ROBOTS, "text/plain; charset=utf-8")
if mode == "maint503":
return self._send(503, MAINT_HTML, "text/html; charset=utf-8", {
"Retry-After": format_datetime(REOPEN, usegmt=True),
"Cache-Control": "no-store",
})
if mode == "maint503nc": # 失敗例:Cache-Control を付けない 503
return self._send(503, MAINT_HTML, "text/html; charset=utf-8", {
"Retry-After": format_datetime(REOPEN, usegmt=True),
})
if mode == "maint200": # 失敗例:200 でメンテナンス画面
return self._send(200, MAINT_HTML, "text/html; charset=utf-8")
return self._send(200, NORMAL_HTML, "text/html; charset=utf-8")
do_HEAD = do_GET
if __name__ == "__main__":
ThreadingHTTPServer(("127.0.0.1", 18244), H).serve_forever()
$ echo maint503 > /dev/shm/t240/py/mode
$ curl -sS -I http://127.0.0.1:18244/
HTTP/1.0 503 Service Unavailable
Server: maint/1.0 Python/3.13.18
Date: Sun, 01 Nov 2026 06:20:18 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 206
Retry-After: Thu, 29 Oct 2026 14:00:00 GMT
Cache-Control: no-store
$ curl -sS -I http://127.0.0.1:18244/robots.txt
HTTP/1.0 200 OK
Server: maint/1.0 Python/3.13.18
Content-Type: text/plain; charset=utf-8
Content-Length: 23
HTTP/1.0 と出るのは、BaseHTTPRequestHandler の既定のプロトコルの版が HTTP/1.0 のためです。状態コードとヘッダーの意味は変わりません。Flask・FastAPI・Express などでも、503の応答に Retry-After と Cache-Control: no-store を足し、robots.txt を判定の外に置く、という形は同じです。
よくある失敗の再現(200のメンテナンス画面・robots.txtまで503)
この節では、メンテナンスでよく起きる失敗を手元で再現した応答の原文と、公式の記述から何が起きるかが分かります。
いちばん多いのは「見た目は正しいメンテナンス画面なのに、状態コードが200」という失敗です。 ブラウザでは区別がつかないため、応答の1行目を見ないと気づきません。
メンテナンス画面の返し方
見分ける問い:「curl -I の1行目は503か」
robots.txt の扱い
見分ける問い:「/robots.txt だけ200か」
長く止めるとき
見分ける問い:「1〜2日で戻せるか」
200で返した失敗例(nginx の18241番)と、robots.txt まで503にして Retry-After も付かない失敗例(18242番)の原文です。
$ curl -sS -I http://127.0.0.1:18241/
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html
Content-Length: 458
ETag: "6ae6d9bd-1ca"
$ curl -sS -I http://127.0.0.1:18241/robots.txt
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 458
$ curl -sS -I http://127.0.0.1:18242/
HTTP/1.1 503 Service Temporarily Unavailable
Server: nginx
Content-Type: text/html
Content-Length: 458
ETag: "6ae6d9bd-1ca"
$ curl -sS -I http://127.0.0.1:18242/robots.txt
HTTP/1.1 503 Service Temporarily Unavailable
$ curl -sS -o /dev/null -L -w '%{http_code} %{url_effective} redirects=%{num_redirects}\n' http://127.0.0.1:18251/blog/a
200 http://127.0.0.1:18251/maintenance.html redirects=1
18241番では robots.txt の URL にまでメンテナンス画面の HTML が200で返っています(Content-Type が text/html、長さ458バイト)。18242番の add_header Retry-After 3600; は always が無いため、503には付きませんでした。302の例(Apache の18251番)は、元の URL がすべて /maintenance.html へ移り、移動先が200で返ります。
| 失敗 | 手元の応答(原文) | 公式の記述から起きること | 直し方 |
|---|---|---|---|
| 200でメンテナンス画面 | HTTP/1.1 200 OK(中身はメンテナンス画面) | 中身がページとして処理される。エラーのような中身ならソフト404 | 503で返す |
| 302でメンテナンス画面へ | HTTP/1.1 302 Found → 200 | 移動先の200の画面を処理することになる | 元の URL のまま503 |
| robots.txt まで503 | HTTP/1.1 503 Service Temporarily Unavailable | 最初の12時間はサイト全体のクロールが止まる | robots.txt を判定の外へ |
| robots.txt に HTML を200 | Content-Type: text/html(長さ458) | 返された内容のとおりに処理される | robots.txt を判定の外へ |
| Retry-After が付かない | 503の応答に Retry-After の行が無い | 再開の目安が伝わらない | nginx は always、Apache は Header always |
| ドロップインが200 | HTTP/1.1 200 OK(X-Powered-By: PHP/8.3.6) | 200の画面と同じ | http_response_code(503) |
| 403・404で止める | (手元では作っていない) | 中身を使わず、登録済みの URL も削除される | 503か200の告知 |
CDN・キャッシュにメンテナンス画面が残る失敗(再現)
この節では、メンテナンスを終えたのに手前のキャッシュが前の応答を返し続ける失敗を、nginx の proxy_cache で再現した結果が分かります。
200で返したメンテナンス画面は、普通のページとしてキャッシュされ、元に戻した後も出続けました。 CDN の代わりに、Python のサーバー(18244番)の手前に nginx の proxy_cache を2つ置いています。18243番は200だけを10分、18245番はどの状態コードも1分キャッシュする設定です(前の nginx の設定全文の後半)。
| キャッシュの設定 | メンテナンス中の応答 | 戻した直後 | 結果(X-Cache-Status) |
|---|---|---|---|
| 200だけ10分 | 200のメンテナンス画面 | 200のメンテナンス画面 | MISS → HIT、HIT |
| 200だけ10分 | 503(no-store) | 200の通常のページ | MISS → MISS |
| どれも1分 | 503(no-store) | 200の通常のページ | MISS → MISS |
| どれも1分 | 503(Cache-Control なし) | 503のまま | MISS → HIT、HIT → 61秒後 EXPIRED で200 |
$ echo maint503nc > py/mode # Cache-Control を付けない503
$ curl -sS -o /dev/null -w '%{http_code} X-Cache-Status=%header{x-cache-status}\n' http://127.0.0.1:18245/q
503 X-Cache-Status=MISS
$ echo normal > py/mode # メンテナンスを終えた
$ curl -sS -o /dev/null -w '%{http_code} X-Cache-Status=%header{x-cache-status}\n' http://127.0.0.1:18245/q
503 X-Cache-Status=HIT
$ curl -sS -o /dev/null -w '%{http_code} X-Cache-Status=%header{x-cache-status}\n' http://127.0.0.1:18245/q
503 X-Cache-Status=HIT
$ sleep 61; curl -sS -o /dev/null -w '%{http_code} X-Cache-Status=%header{x-cache-status}\n' http://127.0.0.1:18245/q
200 X-Cache-Status=EXPIRED
MDN も、503は一時的な状態を示すため通常キャッシュされるべきではなく、修正の後に以前のエラーページが届くおそれがある、と注意しています。503には Cache-Control: no-store を付け、メンテナンスを終えたら CDN のキャッシュを消してから外の応答を確かめます。 商用の CDN が5xxをどれだけキャッシュするかは製品と設定で違うため、使っている CDN の公式ドキュメントで確かめます。
自分で確かめる手順(curl・Search Console)
この節では、自分のサイトのメンテナンス設定が正しいかを、ターミナルの1行と Search Console の画面で確かめる方法が分かります。
ターミナルで1行:curl -sS -I https://自分のサイト/ の1行目と Retry-After を見ます。 複数の URL をまとめて見るなら、次の小さなスクリプトが使えます。robots.txt を必ず入れておきます。
#!/bin/sh
# check503.sh:メンテナンス中の状態コードと Retry-After をまとめて見る
# 使い方:sh check503.sh https://example.com
BASE="$1"
for p in / /blog/ /robots.txt /sitemap.xml; do
curl --noproxy '*' -sS -o /dev/null \
-w "%{http_code} Retry-After=%header{retry-after} Cache-Control=%header{cache-control} $p\n" \
"$BASE$p"
done
$ sh check503.sh http://127.0.0.1:18240 # 正しい例
503 Retry-After=3600 Cache-Control=no-store /
503 Retry-After=3600 Cache-Control=no-store /blog/
200 Retry-After= Cache-Control= /robots.txt
503 Retry-After=3600 Cache-Control=no-store /sitemap.xml
$ sh check503.sh http://127.0.0.1:18242 # 失敗例
503 Retry-After= Cache-Control= /
503 Retry-After= Cache-Control= /blog/
503 Retry-After= Cache-Control= /robots.txt
503 Retry-After= Cache-Control= /sitemap.xml
$ curl -sS -o /dev/null -w '%{http_code} %header{retry-after}\n' \
-A 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' http://127.0.0.1:18240/
503 3600
User-Agent を Googlebot にしても同じ503でした。これは「サーバーが User-Agent で返し方を変えていない」ことの確認で、Googlebot の動きを再現するものではありません。%header{…} は curl 7.84.0 以降で使えます。
Search Console で確かめる:ヘルプによると、URL 検査ツールの「公開 URL をテスト」で、Google がページを取得できたか(「ページの取得」)が分かり、「テスト済みのページを表示」から HTTP ヘッダーを見られます。サイト全体の状況は「設定」の「クロールの統計情報」で、レスポンス別(5XX などの「不正なレスポンス」)とホストのステータス(robots.txt の取得・DNS の解決・サーバー接続)を見られます。
- 1ページの1行目が503かcurl -I の1行目。ブラウザの見た目では200と区別できない
- 2Retry-After が503に付いているかnginx は always、Apache は Header always。日付なら未来の時刻か
- 3/robots.txt だけ200か中身が text/plain の robots.txt で、Disallow: / に変わっていないか
- 4503に Cache-Control: no-store があるかCDN を通した URL でも、戻した後に200になるか
- 5再開後に Search Console で取得できるかURL 検査の公開 URL のテストと、クロールの統計情報の5XXの推移
判断表:500・503・429・200・404のどれを返すか
この節では、止める理由と長さから、どの状態コードを返すかを上から順に決められます。
上から順に当てはめ、最初に当てはまったものを返します。
- 1数時間〜1〜2日の計画メンテナンス → 503+Retry-Afterrobots.txt は200。Cache-Control: no-store
- 2アクセスが集中して処理しきれない → 503API の利用回数の上限なら429。Google はどちらもサーバーエラーとして扱う
- 31日より長く止める → 200の告知ページ注文などの機能だけ止める。再開予定を書く
- 4Googlebot のクロールを減らしたい → 短期間の500・503・429難しければ Search Console の特別リクエスト。401・403は使わない
- 5プログラムの不具合で500が出ている → 原因を直す500は意図して返すものではない。続くと503と同じく削除の対象
- 6ページをやめる → 404・410一時的な停止には使わない
- 7別の URL へ移った → 301メンテナンス画面への302は使わない
| 状況 | 返すもの | Google の扱い(公式) | 注意 |
|---|---|---|---|
| サーバー移転・DB 更新で2時間止める | 503+Retry-After | クロールが一時的に減る | robots.txt は200 |
| セール開始でアクセスが集中 | 503(混雑時だけ) | 過負荷の合図として扱われる | 平常時に戻ったら2xx |
| 店舗の休業で1週間受注を止める | 200のまま機能だけ止める | ページはそのまま処理される | 告知と構造化データを更新 |
| 3日以上サーバーが止まる見込み | 静的な告知ページを200 | 503が数日続くと削除の場合あり | 別のサーバーに告知を置く |
| クローラーの負荷が高すぎる | 短期間の503・429 | ホスト名全体のクロールが減る | 新しいページの発見も遅れる |
| サービスを終える | 404・410 | インデックスから削除される | 移転先があるなら301 |
「クロール頻度を下げる」のページは、クローラーの急増はファセットナビゲーション・並べ替え・カレンダーなど URL の作りが原因のことが多いので、まずアクセスログで原因を確かめるよう書いています。エラーを返すのは緊急時の手段です。
よくある質問
Q. 500と503の違いは何ですか? A. 500は「サーバーの中で想定外の故障が起きた」、503は「メンテナンスや過負荷で今は一時的に処理できない」という意味です。503には Retry-After で再開の目安を付けられます。Google 検索の公式ページでは、500・502・503は同じ行にまとめられ、同じ説明が書かれています。
Q. 503はSEOに影響しますか? A. 短時間なら、クロールのペースが一時的に落ち、2xx に戻れば徐々に回復します。公式ページは、同じ URL で数日にわたってエラーが返るとインデックスから削除される場合がある、と書いています。目安は数時間〜1〜2日です。
Q. 500より503のほうが検索順位に有利ですか? A. 公式ページに、500と503で順位が変わるという記述はありません。どちらもサーバーエラーとして同じ扱いが書かれています。メンテナンスで503を選ぶのは、意図して返せること、Retry-After を付けられること、利用者にも一時的と伝わることが理由です。
Q. メンテナンス中は何日まで503で返せますか? A. 「クロール頻度を下げる」のページは数時間〜1〜2日を目安とし、それを超える期間には勧めていません。「一時停止または無効化する」のページは、1日より長く止める場合は200で告知のホームページを出す方法を挙げています。
Q. Retry-After を付けないとどうなりますか? A. 503であることは変わりません。Google は503・429に Retry-After を付けられると案内していますが、付けなかった場合の違いや、値をどう使うかの詳細は書いていません。再開の目安を伝える手段として付けておくと、人のツールやクローラーに同じ情報を渡せます。
Q. robots.txt も503にしてよいですか? A. 避けます。robots.txt が5xxを返すと、最初の12時間はサイト全体のクロールが止まり、その後30日までは前回取得できた版が使われます。一時停止のページも、robots.txt では503を返さず、クロールを許可したままにするよう書いています。
Q. メンテナンス画面を200で返すと何が問題ですか? A. 5xx の中身は無視されますが、200の中身はページとして処理されます。中身がエラーのようならソフト404と判定され得ます。手元の再現では、200で返した画面が CDN 代わりのキャッシュに残り、元に戻した後も出続けました。
Q. 429とは何が違いますか? A. 429は「リクエストが多すぎる」という意味で、API の利用回数の上限などで返します。Google のクローラーは429を過負荷の合図として扱い、サーバーエラーとみなすと公式に書かれています。サイト全体のメンテナンスには503を使います。
Q. WordPress の「Briefly unavailable for scheduled maintenance」はSEO の面で問題のない状態ですか? A. 本体の既定の動きは503と Retry-After: 600 で、公式の案内に沿った形です。ただし wp-content/maintenance.php(ドロップイン)を置くと状態コードはそのファイルしだいになり、状態コードを書かないと200になりました。
Q. 503を返している間に Search Console で何を見ればよいですか? A. 「設定」の「クロールの統計情報」で、レスポンス別の5XX と、ホストのステータスの robots.txt の取得を見ます。再開後は URL 検査ツールの「公開 URL をテスト」で、ページの取得が成功するかを確かめます。
Q. 403や404でクローラーを止めてもよいですか? A. 勧められていません。公式ページは、クロール頻度の制限に401・403を使わないよう書いており、4xx(429以外)を返した URL はインデックスから削除されます。一時停止のページも、403・404・410や noindex はサイトが検索から消えるため避けるよう書いています。
まとめ
- 500と503は意味が違うが、Google の扱いは同じ行:どちらもクロールが減り、繰り返せばインデックスから削除される。順位の差は公式に書かれていない。
- 計画メンテナンスは数時間〜1〜2日なら503+Retry-After:それより長いなら200の告知ページで機能だけ止める。
- robots.txt は200のまま:5xxだと最初の12時間はサイト全体のクロールが止まる。Disallow: / にもしない。
- ヘッダーは always で付ける:nginx の add_header、Apache の Header は書き方しだいで503に付かなかった。WordPress のドロップインは状態コードを自分で出す。
- 503には Cache-Control: no-store、終わったらキャッシュを消す:200の画面や no-store の無い503は、戻した後もキャッシュから出続けた。
参考・出典
確認日はいずれも 2026年10月29日です。
- Google 検索セントラル「HTTP ステータスコード、ネットワーク エラー、DNS エラーが Google 検索に与える影響」(英語版 最終更新 2026-02-04、日本語版 2026-03-06):https://developers.google.com/search/docs/crawling-indexing/http-network-errors
- Google 検索セントラル「Google のクロール頻度を下げる」(英語版 最終更新 2026-10-06、日本語版 2026-10-11):https://developers.google.com/search/docs/crawling-indexing/reduce-crawl-rate
- Google 検索セントラル「Google による robots.txt の解釈」(英語版 最終更新 2026-10-23、日本語版 2026-10-26):https://developers.google.com/search/docs/crawling-indexing/robots/robots_txt
- Google 検索セントラル「ウェブサイトを一時停止または無効化する」(最終更新 2025-12-31):https://developers.google.com/search/docs/crawling-indexing/pause-online-business
- Search Console ヘルプ「クロールの統計情報レポート」:https://support.google.com/webmasters/answer/9679690
- Search Console ヘルプ「URL 検査ツール」:https://support.google.com/webmasters/answer/9012289
- MDN「503 Service Unavailable」:https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Status/503
- MDN「Retry-After」:https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Retry-After
- nginx「Module ngx_http_headers_module」(add_header と always):https://nginx.org/en/docs/http/ngx_http_headers_module.html
- Apache HTTP Server「mod_headers」(Header の always と onsuccess):https://httpd.apache.org/docs/2.4/mod/mod_headers.html
- WordPress Developer Resources「wp_maintenance()」:https://developer.wordpress.org/reference/functions/wp_maintenance/
- WordPress Developer Resources「wp_is_maintenance_mode()」:https://developer.wordpress.org/reference/functions/wp_is_maintenance_mode/
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「503とSEO|500との違い・Googleの扱いとメンテナンス時の正しい返し方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。