No.004 「型が不明」なsitemap.xmlと数週間格闘したっていう話

「型が不明」なsitemap.xmlと数週間格闘したっていう話
きっかけ
Cloudflare Pagesでホストしている自分のサイト(Next.js製)で、Google Search Consoleを開いたらサイトマップのステータスが「取得できませんでした」になっていた。
とりあえずブラウザで https://tsukuneserver.xyz/sitemap.xml を開いてみる。普通にXMLが表示される。curlでも叩いてみる。200 OK。Googlebotのユーザーエージェントを偽装しても問題なく取得できる。
「じゃあ何が悪いんですか……」
これが数週間続く戦いの始まりだった。
第一の容疑者: robots.txt
まず疑ったのはrobots.txt。Next.jsの app/ ディレクトリでは本来 robots.ts としてTypeScriptで書くべきところを、拡張子を .txt のままにしていた。
これが地味に厄介で、おそらくNext.jsは拡張子でファイルの扱いを決めるため、.txt だとコードがコードとして実行されず、ソースコードがそのままテキストとして配信されてしまっていた。
app/robots.txt → app/robots.ts にリネームするだけ。ちゃんとしたrobots.txtが返るようになった。
でも、サイトマップのエラーは消えなかった。
第二の容疑者: sitemap.tsの中身が薄すぎた
次に app/sitemap.ts を見直したら、中身がトップページ1件だけしか登録されていなかった。そもそもこれではサイトマップとしての体をなしていない。
/about、/blog、/contact、/server、/specs を追加して、計6ページ分のURLを含む、まともなサイトマップに拡充した。
これも直した。でも、まだ「取得できませんでした」のまま。
実は容疑者はもう一人いた: 過去の誤ったサイトマップ提出
あとから気づいたのだが、実はSearch Console内にもっと前に自分で提出した、間違ったサイトマップの記録が残っていた。
当時はまだNext.jsの sitemap.ts の仕組みをよく理解しておらず、Search Consoleのサイトマップ欄に手動で
https://tsukuneserver.xyz/about.html
のような、存在しない .html 拡張子付きのURLを直接入力して提出していた。Next.jsの app/ ディレクトリはそもそも .html という実ファイルを生成する構成にはなっていないので、これは最初から存在しないパスを指していたことになります。
Search Console上には、この過去の誤った提出がそのまま「エラー」として残り続けていた。新しく正しい sitemap.ts を用意しても、画面には昔提出した無効なURLの記録が亡霊のように居座っていて、パッと見て「まだ直っていない」ように見えてしまっていた。
これに気づいてからは、Search Consoleの「サイトマップ」一覧画面で過去の誤ったエントリ(about.html など)を一つずつ削除し、正しいエントリだけが残るように整理した。
第三の容疑者: wwwサブドメイン
だんだん怪しくなってきたのが www.tsukuneserver.xyz だった。Cloudflare側の推奨事項にも警告が出ていて、www 付きドメインにちゃんとアクセスできていないことが判明。
Cloudflare PagesのWorkerルートとRedirect Ruleが競合していたので、一旦カスタムドメイン登録を外し、通常のDNS CNAME + Redirect Ruleで組み直した。最終的に https://www.tsukuneserver.xyz/* から https://tsukuneserver.xyz/${1} への301リダイレクトがちゃんと動くようになった。
SSL/TLS設定(Full)、Bot Fight Mode、WAF、Browser Integrity Checkも一通りすべて確認したが、どれも原因ではなかった。
それでも消えないエラー
正直、ここまでやって「もう直っただろう」と思っていた。しかしSearch Consoleを開くと、変わらず「取得できませんでした」。
これは流石にブチギレ
それから1週間放置してやっとやる気になったので調べてみると、とても興味深い情報にたどり着いた。
サイトマップのXML自体が正常でも、Googleが「ドメイン+URLパスの組み合わせ」に対して、過去の失敗状態を内部的に記憶し続けてしまうことがある
要するに、こちら側の設定を全部直しても、Google側が同じURL文字列に対して「前に失敗した」という記憶を引きずっている可能性がある、ということだった。
最後の一手: URLを変える
半信半疑で試したのが、サイトマップのURLにクエリパラメータを足すという方法。
https://tsukuneserver.xyz/sitemap.xml?v=2
Googleから見れば「別のURL」に見えるので、まっさらな状態で再評価してもらえるはず、という理屈。
Search Consoleで新規URLとして送信した瞬間、今までの苦労が嘘だったかのように**即座に「正常に処理されました」**に変わった。検出ページ数は7件。
robots.tsの sitemap: フィールドも同じURLに合わせて更新して完了。
振り返って
最終的に site:tsukuneserver.xyz で検索したら、トップページ、/about、/server、/specs、/contact、/blog が全部インデックスされていた。
今回の件で学んだのは:
- 拡張子は本当に見落としやすい —
robots.tsとrobots.txtは名前が似ているのに挙動が全く違う - 過去に手動提出した誤ったサイトマップは自分で消さないと残り続ける — Search Consoleは親切に古いエラーを片付けてはくれない。存在しないURLを提出した記録がある場合は、一覧から手動で削除する必要がある
- wwwのあり・なしは両方ちゃんと見る — ドメインプロパティを使うなら片方だけ動いていても意味がない
- Google側にも「URL単位のキャッシュされた失敗」がある — 技術的に完璧に直しても解消しないことがあり、その場合はURLそのものを変えて再評価させるのが有効な回避策になる
自分の設定ミスを疑うだけでなく、「Google側が引きずっている可能性」まで視野に入れないと、永遠にイライラし続けることになっていたかもしれない。
Authored by Tsukune.
