CLAUDE LABEN
TEACHERS — AnthropicがClaude for Teachersを公開。米国K-12の認証済み教員に、プレミアム機能と授業向けスキル、全50州の学習指導基準に沿ったカリキュラム連携を無償提供しますADMIN — Claude Enterprise全組織でAdmin APIがベータ提供に。メンバーと招待の操作はベータヘッダー不要、グループとカスタムロールは専用ヘッダーが必要ですM365 — Microsoft 365コネクタに書き込みツールが追加。メールの下書き・送信・整理、カレンダー操作、OneDriveとSharePointのファイル作成・更新まで任せられますMCP — --mcp-configや.mcp.jsonのサーバ単位request_timeout_msが無視され、新規セッションで60秒既定のままタイムアウトする不具合が修正されましたSUBAGENT — --forward-subagent-textとCLAUDE_CODE_FORWARD_SUBAGENT_TEXTが追加。サブエージェントのテキストと思考をstream-json出力に含められますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。残り7日、speed: "fast" はエラーになるためOpus 4.8への移行をご確認くださいTEACHERS — AnthropicがClaude for Teachersを公開。米国K-12の認証済み教員に、プレミアム機能と授業向けスキル、全50州の学習指導基準に沿ったカリキュラム連携を無償提供しますADMIN — Claude Enterprise全組織でAdmin APIがベータ提供に。メンバーと招待の操作はベータヘッダー不要、グループとカスタムロールは専用ヘッダーが必要ですM365 — Microsoft 365コネクタに書き込みツールが追加。メールの下書き・送信・整理、カレンダー操作、OneDriveとSharePointのファイル作成・更新まで任せられますMCP — --mcp-configや.mcp.jsonのサーバ単位request_timeout_msが無視され、新規セッションで60秒既定のままタイムアウトする不具合が修正されましたSUBAGENT — --forward-subagent-textとCLAUDE_CODE_FORWARD_SUBAGENT_TEXTが追加。サブエージェントのテキストと思考をstream-json出力に含められますDEADLINE — 7月24日にOpus 4.7のfastモードが削除されます。残り7日、speed: "fast" はエラーになるためOpus 4.8への移行をご確認ください
記事一覧/Claude Code
Claude Code/2026-05-19中級

Claude Code の WebFetch が 403 や空ページを返す時の原因と対処

Claude Code の WebFetch が 403 を返したり、本文が抜けた空のページを返す現象には、いくつか定番の原因があります。Cloudflare のボット検知、クライアントレンダリング、ドメイン許可リスト、キャッシュの4点を切り分けながら、それぞれの実用的な対処法を整理します。

claude-code129webfetchtroubleshooting61cloudflarespaclaude-in-chrome4

「WebFetch で技術ドキュメントを読ませようとしたら、403 が返ってきた」「200 は返っているのに本文がほぼ空で、ナビゲーションだけが残っている」— Claude Code を日常的に使う中で、自動化スクリプトのある日突然うまく動かなくなる代表的な現象です。私自身、自分の運営する Lab 系サイト4本の自動投稿パイプラインで、月に何度かこの種のトラブルにぶつかります。

落ち着いて切り分ければ原因は4つに集約できます。それぞれの見分け方と、私が実運用で採用している対処を順に整理しておきます。

何が起きているのか — WebFetch の挙動を先に押さえる

Claude Code に組み込まれた WebFetch ツールは、内部的には Anthropic 側のサーバーが対象 URL に対して HTTP GET を発行し、得られた HTML をテキスト化してモデルに渡す仕組みです。ここで重要なのは、ブラウザではないという点です。

具体的には次の挙動を持ちます。

  • JavaScript を実行しない: React や Next.js、Vue で構築されたクライアントレンダリング系のページは、初期 HTML のシェル(ローディングスピナーやナビゲーション)だけが返ります。
  • 固定の User-Agent を持つ: 一部のサイト(特に Cloudflare の Bot Fight Mode を有効にしているもの)は、この User-Agent を機械的に弾きます。
  • 結果を一定時間キャッシュする: 同一 URL に対して短時間に再リクエストすると、サーバー側のキャッシュから古いレスポンスが返ることがあります。
  • ドメイン許可リストが効く: --allowedDomains を絞っている運用では、許可対象外のドメインへのアクセスが事前にブロックされます。

つまり「403」「空ページ」「タイムアウト」「想定と違う古い情報」のいずれも、原因はこの4軸のどれかに収まります。

原因1: Cloudflare などのアンチボット保護で 403

Anthropic のヘルプドキュメント、GitHub の生のファイル、Stack Overflow など、Cloudflare の手前にいるサイトでは、WebFetch のリクエストがしばしば 403 で弾かれます。エラーメッセージとしては次のような形で返ってくることが多いです。

Web fetch failed: HTTP 403 — the server refused to fulfill the request

これは Cloudflare の Managed Challenge や Bot Fight Mode が、WebFetch の User-Agent や TLS フィンガープリントを「明らかにブラウザではない」と判定して落としているサインです。私の経験では、特に技術ドキュメントを多用するエージェント運用で頻発します。

私が使っている対処

まず、対象 URL に 同じ情報の代替ソース がないかを最初に検討します。例えば GitHub の https://github.com/owner/repo/blob/main/README.md は 403 になりがちですが、https://raw.githubusercontent.com/owner/repo/main/README.md ならテキスト本文がそのまま取れます。同じく公式ドキュメントには、API リファレンス用の *.jsonllms.txt を公開しているケースが増えています。

それでも当該 URL を取りに行く必要があるなら、Claude in Chrome(Chrome MCP)にフォールバックします。プロンプトの中で、こう指示しています。

WebFetch でこのURLを試してください。もし 403 または空ページが返ったら、
mcp__Claude_in_Chrome__navigate でアクセスし、
mcp__Claude_in_Chrome__get_page_text で本文を読み取ってください。
URL: https://example.com/docs

Claude in Chrome は実ブラウザで動くため、Cloudflare のチャレンジを通過できる場合がほとんどです。私のアプリ事業(AdMob を含む収益化)でも、AdMob の管理画面のような JavaScript 重めの SaaS は Chrome MCP 経由でないと触れません。

curl や wget を Bash ツールから叩く方法もありますが、Cowork モードや一部の環境ではネットワーク制限により失敗します。さらに WebFetch を回避する目的での bash 経由のフェッチは Cowork の方針として推奨されていません。Claude in Chrome を使うほうが筋が良いです。

原因2: クライアントレンダリングのページで本文が空

レスポンスは 200 OK なのに、<main> の中身が「Loading...」や「Enable JavaScript」だけ、というケースです。これは原因1よりも厄介で、エラーが出ないため気づきにくいのが特徴です。

代表的なサインは次のようなものです。

  • ナビゲーションのリンク群は読めるのに、記事本文が見つからない
  • 検索結果のリストが「0件」と表示される(実際にはサイトに記事が存在する)
  • 価格表のテーブルが空欄

これは React や Next.js などで構築された SPA で起きます。初期 HTML にはアプリケーションのシェルしか含まれず、本文は fetch() 後にクライアントで描画されるためです。

対処: SSR の有無を確認し、Claude in Chrome へ切り替える

切り分けは、ブラウザの「ページのソースを表示」(View Source)で対象の本文テキストが含まれているかどうかで判断できます。含まれていなければ WebFetch では取れません。

最近の Next.js なら App Router 化で SSR されている場合もありますが、Vercel デプロイの古い構成や、Vite + React + React Router の構成では、本文がクライアントレンダリングのままになっていることが多いです。

この場合、私のワークフローは以下のようになります。

このページは SPA で、WebFetch では本文が取れない可能性が高いです。
mcp__Claude_in_Chrome__navigate でアクセスしてから、
mcp__Claude_in_Chrome__get_page_text でレンダリング後の本文を取得してください。

私が運営する Lab 系4サイト(Claude Lab / Gemini Lab / Antigravity Lab / Rork Lab)も Next.js 16 + App Router 構成ですが、念のためビルド後の view-source: で記事本文が HTML に含まれていることを確認するようにしています。WebFetch で取れることは、AI クローラに対するアクセシビリティそのものでもあるからです。

原因3: ドメイン許可リスト(--allowedDomains)で事前ブロック

Claude Code を CI や定期実行で動かす運用では、--allowedDomains でフェッチ可能なドメインを絞り込んでいるケースが少なくありません。この場合、許可対象外のドメインを WebFetch しようとすると、次のような表示が出ます。

WebFetch is not allowed for domain: stackoverflow.com
Allowed domains: docs.anthropic.com, github.com

仕様通りの挙動です。許可確認ダイアログを抑止しつつ、安全な範囲だけにフェッチを限定したいときに使うフラグですが、許可リストの更新を忘れると本番ジョブが静かに止まります。

対処

私は2014年から個人でアプリ開発を続けていますが、長く運用するほど許可リストは「育てる」ものになります。スクリプト側で固定するのではなく、設定ファイルに切り出しておくと管理が楽です。

# 例: ~/.claude-code/allowed-domains.txt として管理
docs.anthropic.com
www.anthropic.com
raw.githubusercontent.com
api.github.com
developer.apple.com
developer.android.com
admob.google.com
firebase.google.com

CI からは次のように渡します。

claude code --allowedDomains "$(paste -sd, ~/.claude-code/allowed-domains.txt)" ...

新規ドメインへのアクセスが必要になった時は、許可リストへの追記を Pull Request にして、変更履歴を残しておくと、後から「なぜこのドメインを許可したのか」を辿れます。

原因4: 古いキャッシュが返ってきている

WebFetch は内部で短時間のキャッシュを持っており、同一 URL に対しての再リクエストはキャッシュから返されることがあります。リアルタイムのステータスページや、価格を確認したいページで、「更新したはずなのに変わらない」という現象の正体はこれです。

対処

シンプルですが、URL にクエリパラメータを追加するのが最も確実です。

https://example.com/status?_=1716120000

末尾の _= パラメータは多くのサーバーで無視されるため、コンテンツには影響しません。一方、WebFetch にとっては「別の URL」として扱われ、キャッシュをバイパスできます。

ただし、本来キャッシュは料金とレイテンシの両方を抑えるための仕組みです。やみくもにバイパスするとコストに跳ね返るので、本当にリアルタイム性が必要な場面に限定するのがコツです。私の運用では、毎朝の SEO レポート生成(GA / GSC)のように 24 時間で更新される情報には、URL に日付付きパラメータを足すようにしています。

切り分けの順序を固定しておく

実運用で大事なのは、「いま起きている現象が4つのどれなのか」を最短で見極めることです。私が日常的に使っているチェックリストはこの順序です。

  1. レスポンスのステータスコードを確認します。403 / 429 なら原因1、200 なら原因2 か 4 を疑います
  2. view-source: で本文 HTML が含まれているかを確認します。含まれていなければ原因2、Claude in Chrome へ切り替えます
  3. --allowedDomains の設定を確認します。CI 環境で動かしているなら最優先で確認します
  4. URL にダミークエリを足して再フェッチします。それで結果が変わるなら原因4です

ここまで切り分けても解決しないことは、私の経験ではほとんどありません。逆に言えば、原因不明のまま何度も WebFetch を叩き続けると、API 利用料だけが積み上がっていくので、最初の段階で見極める習慣をつけたほうが結果的に安く済みます。

次のアクション

WebFetch で詰まった時の現実的な次の一歩を一つだけ挙げるなら、Claude in Chrome(Chrome MCP)を別チャネルとして常に手元に置いておく ことだと感じています。Cowork の右上から有効化できますし、403 と空ページの両方を一度に解消できます。私自身、Lab 系サイトの自動運用と、累計5,000万ダウンロードのアプリ事業の両方でこの組み合わせを使っていますが、運用コストの観点でも安定性の観点でも、フォールバック先を一つ用意しておくことの価値は大きいです。

実装の参考になれば幸いです。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-06-18
壊れた settings.json で Claude Code が起動しなくなったとき — セーフモードの挙動と設定の分け方
settings.json の構文ミスで Claude Code が起動しなくなったときに、どの階層が壊れているかを切り分けて数分で復旧する手順と、自動運用で壊れにくい設定の分割・検証パターンをまとめました。
Claude Code2026-06-10
git add -A が .bak バックアップまで巻き込む — in-place 修正スクリプトと自動コミットの落とし穴
sed -i や自作の --fix スクリプトが残す .bak バックアップを git add -A が無言で取り込み、本番リポジトリに混入させてしまう問題。なぜ気づきにくいのか、scoped add と .gitignore でどう塞ぐかを実例で整理します。
Claude Code2026-06-09
前回の記事本文が別の記事に紛れ込む — 固定名の一時ファイルに残る残骸の罠
Claude Code の自動化で、固定名の一時ファイルに前回の中身が残り、まったく別の記事に古い本文が混入する。書き込みが無音で失敗する仕組みと、ユニーク名+挿入後の grep 照合で防ぐ方法を記録します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →