ソフト404エラーとは?原因の見つけ方と正しい直し方
結論: ソフト404とは、訪問者には「見つかりません」と表示される(あるいはほとんど何も表示されない)のに、サーバーが 404 ではなく成功を表すステータス 200 を返しているページのことです。Google はこれをエラーとして扱い、2xx の応答の内容がエラーを示している場合に、Search Console でソフト404として報告します。直し方は、サーバーが実態に合ったステータスを返すようにすることです。削除したページには 404 か 410、移転したページには同等の新しいページへの 301、存在すべきページには実際のコンテンツを用意します。
ソフト404とは?
Web サーバーの応答は、必ずステータスコードから始まります。コードはコンテンツよりも前に届きます。200 は「問題なし、ページはこれです」、404 は「ここには何もありません」という意味です。ソフト404は、この2つが食い違っている状態です。画面には「見つかりません」「0 件」と表示されているか、読む価値のあるものが何も表示されていないのに、ステータスは 200 を返しています。
このケースは、Google のHTTP ステータスコードとネットワークエラーに関するドキュメントで説明されています。2xx の応答では、Google はコンテンツを処理の対象にします。そのコンテンツが空のページやエラーメッセージのようにエラーを示していると、Search Console にソフト404エラーとして表示されます。本物の 4xx ステータスであれば、Google はその URL のコンテンツをまったく使いません。
違いはターミナルで確認できます。この問題を抱えているサイトで、存在しないアドレスにリクエストを送ると、次のようになります(アドレスは仮のものです)。
$ curl -s -o /dev/null -w "%{http_code}\n" https://your-site.example/page-that-does-not-exist
200
正しい応答は 404 です。訪問者の目には、どちらも同じ親切な「ページが見つかりません」の文面が映ります。違うのはステータスだけですが、クローラーが最初に読むのはステータスです。
名前の「ソフト」は「軽い」という意味ではありません。サーバーは「問題なし」と言っているのに、ページは「問題あり」と言っている、ということです。
ソフト404はなぜ問題なのか?
確認されていることと、そうでないことを分けて整理します。
確認されていること:
- Search Console は該当の URL をソフト404エラーとして一覧にします。つまり、Google 自身がこれを問題と見ています。
- 本物の 404 や 410 であれば、Google はその URL のコンテンツを使いません。200 の場合は、コンテンツから「このページはエラーかどうか」を Google が推測することになります。
確認されていないこと: 順位への直接的な影響です。Google はレポートの中でこのエラーに名前を付けていますが、ソフト404がサイトのほかのページの評価を下げるとは述べておらず、それを裏付ける出典も見つかっていません。「ソフト404はSEOを破壊する」といった主張には慎重になってください。
私たちの見解(意見であり、それ以上のものではありません): 価値のないページを検索結果の候補として差し出すべきではありませんし、直すコストは小さくて済みます。さらに、Google とは関係のない実務上の理由もあります。リンク切れチェッカーや死活監視ツールはステータスコードを読みます。どのアドレスも 200 を返すと、これらのツールはリンクが切れていると教えてくれません。古いリンクをたどってきた訪問者にも、ページがなくなったことは伝わりません。
ソフト404の原因は?
ソフト404は、たいてい次のようなパターンで生まれます。
- すべてのパスに同じ殻を返すシングルページアプリ(SPA)。 どのアドレスにも、サーバーはステータス 200 でアプリを返します。「見つかりません」と表示されるのは JavaScript が動いたあとですが、ステータスはそれより前に決まっていて、200 です。Google はクロール、レンダリング、インデックス登録の順に処理し、ステータス 200 のページはレンダリングの待ち行列に入ります。この仕組みは Google のJavaScript SEO の基本で説明されています。スクリプトをまったく実行しないクローラーがあることも、頭に入れておいてください。
- ステータス 200 のままの見栄えのよいエラーページ。 CMS、フレームワーク、プロキシの設定がデザインされた「ページが見つかりません」のテンプレートを表示しているのに、ステータスの設定を忘れているケースです。
- 中身が空の一覧ページ。 カテゴリ、タグ、サイト内検索のページに該当するものが1件もなくても、200 を返して「0 件」や空の枠を表示してしまいます。
- 売り切れ・販売終了の商品。 ページは残り、「在庫なし」程度の表示しかありません。本物の商品説明と在庫についての案内がまだ載っているページは、ただのお知らせだけのページとは別の扱いになります。
- すべてをトップページへリダイレクトする。 削除したページの訪問者をトップページに送ると、無関係なコンテンツが 200 で返ります。トップページが、なくなったページの代わりになることはめったにありません。
ほかに、内容の薄いページも原因になります。プレースホルダーや作りかけのセクションのように、ほとんど中身のないテンプレートです。エラーメッセージや空のページのように見えるコンテンツは、誰もエラーページにするつもりがなくても、そう判定される可能性があります。
ソフト404を見つける方法
方法は3つあり、互いに補い合います。
- Search Console。 「ページのインデックス登録」レポートで、理由が「ソフト 404」になっているものを探します。Google が自らそう分類した URL が並びます。「URL 検査」を使うと、個別のアドレスについて Google が取得した内容を確認できます。
- ターミナル。 存在し得ないアドレスにリクエストして、ステータスを読みます(コマンドは下記)。
- ブラウザー。 デベロッパーツールを開いて「ネットワーク」(Network)タブに切り替え、でたらめなアドレスを読み込み、最初のリクエストのステータスを見ます。ページの見た目はどのステータスでも同じなので、画面を眺めても分かりません。
ターミナルでの確認には、次のコマンドが使えます。-L オプションはリダイレクトをたどるので、アドレスが最終的にどこに着くかも分かります。
curl -s -L -o /dev/null -w "%{http_code} %{url_effective}\n" https://your-site.example/page-that-does-not-exist
望ましいのは 404 です。200 https://example.com/ が返ってきたら、サーバーが未知のアドレスをトップページへ転送しています。curl -I ではなく、ここで示したように GET を使ってください。サーバーによっては、HEAD リクエストに通常のリクエストとは異なる応答を返すことがあるためです。
確認は外部から行います。アプリケーションに直接ではなく、公開されているアドレスにリクエストしてください。手前に CDN、キャッシュ、ファイアウォールがあると、応答が変わることがあります。
SEOgrinder がソフト404を調べる方法
SEOgrinder の無料スキャンは、存在し得ないランダムな名前のアドレスを作り、あなたのサイトにリクエストします。200 が返ってきたら、指摘として報告します。そのアドレスからトップページへのリダイレクトも、最終的に 200 になるので同じ扱いです。結果は「Google 上のページ」タブの「インデックス」カードに、「存在しないアドレスは正しく 404 を返しています」あるいは「存在しないアドレスが 404 ではなく 200 を返しています」という1行で表示されます。指摘があれば、本物の 404 か 410 を返すようにという助言つきでタスク一覧に入ります。
正直に言うと、限界が2つあります。1つ目に、このテストが調べるのは、存在しないアドレスをサーバーがどう扱うかです。実在する URL のうちどれを Google がソフト404に分類したかは分かりません。個別の URL についての判断は Search Console で確認します。Search Console に接続したローカル環境の SEOgrinder なら、スキャンしたページについて保存されたインデックスの状態も読み取り、Google がソフト404として扱っている場合にはそう知らせます。2つ目に、内容の薄い自分のページが Google から空に見えるかどうかは、このテストでは判断できません。サイトの巡回では、内容の薄いページや壊れた内部リンクを指摘します。問題は、そうした場所から始まることが多いのです。
どのステータスコードが正しい?判断表
正しい応答は、そのページについて本当のことは何かで決まります。ステータスを事実に合わせるのであって、その逆ではありません。
| 状況 | 正しい応答 | 補足 |
|---|---|---|
| ページが完全になくなり、代わりになるものもない | 404 または 410 | デザインされたエラーページでも構わないが、エラーのステータスを返すこと |
| ページが新しいアドレスに移った | 同等の新しいページへの 301(または 308) | 移転先を処理してほしいという強いシグナル |
| 移転が本当に一時的なもの | 302(または 307) | 弱いシグナルなので、恒久的な移転には使わない |
| ページはあるが、内容が薄い、またはほぼ空 | 実際の内容を追加する | 目的がないなら削除する |
| 一覧や検索のページが恒久的に空 | 404 | リンクやサイトマップに載せない |
| 一覧ページが一時的に空なだけ | 役に立つものを表示する | たとえば関連する項目と案内を表示し、ステータスは 200 |
| 商品が完全になくなった | 404 または 410、または直接の後継商品への 301 | トップページへは送らない |
| 商品が一時的に在庫切れ | 実際の内容つきでページを残す | ここでは 200 が正しい |
Google は、301 と 308 を「リダイレクト先を処理すべき」という強いシグナル、302 と 307 を弱いシグナルとして扱います。リダイレクトは標準で最大 10 段階までたどり、リダイレクト元の URL のコンテンツは無視します。ですから、リダイレクトは1回で、最終的なアドレスに直接向けてください。
nginx・Node・SPA でソフト404を直す方法
nginx
次の設定は、デザインされたエラーページを表示しながら、ステータス 404 を保ちます。error_page 404 /404.html; は、=200 を付けない限り元のステータスをそのまま保つので、付けないでください。
server {
root /var/www/example;
error_page 404 /404.html;
location / {
try_files $uri $uri/ =404;
}
location = /404.html {
internal;
}
# 意図して削除したページ
location /old-campaign/ {
return 410;
}
# 移転したページ
location = /old-page {
return 301 https://example.com/new-page;
}
}
Node
データを持つルートでは、まずコードがレコードを検索し、そのあとにステータスを決める必要があります。次の例は Node 標準のモジュールだけで動きます。
import http from 'node:http';
const products = new Map([['blue-mug', 'ブルーのマグカップ']]); // データベースの代わり
http.createServer((req, res) => {
const { pathname } = new URL(req.url, 'http://localhost');
const match = /^\/products\/([a-z0-9-]+)$/.exec(pathname);
const name = match && products.get(match[1]);
res.writeHead(name ? 200 : 404, { 'content-type': 'text/html; charset=utf-8' });
res.end(name ? `<h1>${name}</h1>` : '<h1>ページが見つかりません</h1>');
}).listen(3000);
エラーページは、親切な文面でも凝ったデザインでも構いません。ステータスは 404 のままにします。たいていのフレームワークには、同じ目的の「not found」用の関数やフックがあります。テンプレートを表示するだけのものではなく、ステータスも設定するほうを探してください。
シングルページアプリ
サーバーは、どのパスが実在するかを知っている必要があります。「何が来ても index.html を返す」というよくある安易な近道が、まさに問題の原因です。nginx なら、実在するルートを列挙し、それ以外には 404 を返せます。
location = / {
try_files /index.html =404;
}
location ~ ^/(about|contact|docs)/?$ {
try_files /index.html =404;
}
location / {
try_files $uri =404;
}
スクリプトや画像などのアセットは最後のブロックで見つかり、それ以外のパスはすべて 404 になります。ルートの一覧が長い場合や頻繁に変わる場合は、ビルド時にルーターから生成してください。もう1つの方法は、サーバー側または事前に実際のページを生成し、アドレスごとに専用の HTML ファイルを持たせて、サーバーがそのアドレスに応答できるようにすることです。Google 自身も、ユーザーとクローラーの両方にとってページが速くなり、すべてのボットが JavaScript を実行できるわけではないため、サーバーサイドレンダリングやプリレンダリングは今も良い選択肢だとしています。ステータスコードを設定できない、または現実的でないアプリのために、Google のJavaScript SEO の基本は、さらに2つの方法を挙げています。404 を返すアドレス(たとえば /not-found)へ JavaScript でリダイレクトする方法と、エラーページに JavaScript で <meta name="robots" content="noindex"> を追加する方法です。
変更するたびに curl での確認をやり直し、実在するページ1つ、移転したページ1つ、存在し得ないアドレス1つを試してください。
よくある間違い
- ステータスではなく見た目を直す。 ステータス 200 を返す美しい「見つかりません」ページは、ソフト404のままです。
- 存在しないページをすべてトップページにリダイレクトする。 自分のツールから問題が見えなくなり、訪問者には探していたものと違うものを見せることになります。同等のページにリダイレクトするか、404 を返してください。
error_page 404 =200 /index.html;のような安易な近道。 未知のアドレスがすべて 200 になってしまいます。- ブラウザーだけで確認する。 ブラウザーはどのステータスでも同じ画面を表示します。ステータスを読んでください。
- ステータスを直さず、robots.txt でアドレスをブロックする。 ページを取得できないクローラーは、そのステータスコードを見ることがありません。
- サイトマップに死んだアドレスを残す。 サイトマップに載せるのは、実在して 200 を返すページだけにします。
- レポートがすぐに消えると期待する。 Search Console の表示が変わるのは、Google がその URL を再取得したときです。それがいつになるかは、誰にも約束できません。
よくある質問
ソフト404は順位に悪影響がありますか?
証明されていません。Google が Search Console でエラーとして報告することは、ドキュメントで確認できます。サイトのほかの部分への直接的なペナルティについては、私たちが使った出典のどこにも書かれていません。直す理由は、約束された効果ではなく、誤った応答を返しているからだ、と考えるのが妥当です。
ソフト404と通常の404は同じですか?
違います。404 は誠実な応答で、ステータスがページの不在を伝えています。ソフト404は 200 を返しながら、コンテンツでは逆のことを言っています。
404 と 410 のどちらを返すべきですか?
どちらも 4xx のエラーステータスで、Google はどちらの場合もその URL のコンテンツを使いません。「見つからない」には 404 が普通の応答です。410 は「なくなった」ことを表すので、意図して削除したページに向いています。
独自の 404 ページを作ってもよいですか?
はい、作るべきです。デザインは自由で、トップページへのリンクや検索窓を入れても構いません。ただし、ステータスは 404 にしてください。
サイト全体はどうやって確認すればよいですか?
無料のスキャンで、未知のアドレスにサーバーがどう応答するかを確認し、Google が指摘した URL は Search Console のレポートで確認します。もう1つ、手作業でも見てください。短いお知らせしか載っていないページです。
次の一歩
まず、自分のサイトに存在し得ないアドレスを curl で取得してみてください。404 が返らないなら、そこから直します。そのあと SEOgrinder で無料スキャンを実行し、「Google 上のページ」タブの「インデックス」カードでソフト404の行を確認します。修正後に「再チェック」を押せば、新しい結果が見られます。全体の点検の進め方は、SEOチェックリストの記事にまとめています。