url_not_in_prior_contextエラーの原因 — Web Fetchが動的URLを拒む理由
Web Fetchツールのurl_not_in_prior_contextエラーは、Claudeが自分でURLを組み立てて取得しようとすると発生します。データ持ち出し対策という設計意図と、正しい回避パターンを解説します。
url_not_in_prior_contextはURLの出どころが会話に無いと返る
url_not_in_prior_contextは、Web Fetchツールがフェッチ先のURLを拒否したときに返るエラーコードです。原因は、そのURLが会話のどこにも載っていないことです。代表例は、Claudeが自分でURLを生成・組み立てて渡そうとした場合です。
このエラーが起きる仕組みと、症状から原因を切り分ける手順、web_searchを組み合わせた構成を順に示します。
なぜこのエラーが存在するのか
url_not_in_prior_contextとは、Web Fetchツールが対象URLの出どころを検証し、会話の中に事前に登場していないと判定したときに返すエラーコードです。セキュリティ上の理由から、Web Fetchは会話に一度も登場していないURLを取得できません。
信頼できない入力と機密データを同じ会話で扱う環境でWeb Fetchを有効にすると、データ持ち出し(exfiltration)のリスクがあります。たとえば、悪意あるページの指示でClaudeが機密情報をURLのクエリ文字列に埋め込み、攻撃者のサーバーへ取りにいかせる手口です。Claudeが自分の出力だけに現れるURLを取得できない設計は、この経路のリスクを減らすためのものです。
Web Fetchが取得できるURLとできないURL
取得できる
- ユーザーメッセージに書かれたURL
- クライアント側のツール結果に含まれるURL
- これまでのweb_searchまたはweb_fetchの結果に含まれるURL
クライアント側のツール結果は、Claudeが書いた文字列をそのまま返す場合でも出どころとして認められます。コマンドが入力を印字する場合や、エラーメッセージがURLを引用する場合がこれに当たります。
取得できない
- Claudeの出力にだけ現れるURL
- システムプロンプトにだけ書かれたURL
- コード実行、MCPコネクタ、ツール検索といった他のサーバーツールの結果にだけ現れるURL
システムプロンプトのURLは、同じURLをユーザーメッセージにも書けば取得できるようになります。
エラーの実際の形
Web Fetchツールがエラーに遭遇すると、APIはHTTP 200(成功)を返し、エラーの内容はレスポンス本体のweb_fetch_tool_resultブロックに含まれます。Claudeはこのエラー結果を見たうえでターンを続けます。url_not_accessibleなど他のエラーコードも同じ構造で返り、error_codeの値だけが変わります。
{
"type": "web_fetch_tool_result",
"tool_use_id": "srvtoolu_a93jad",
"content": {
"type": "web_fetch_tool_result_error",
"error_code": "url_not_accessible"
}
}HTTPステータスが200なので、ステータスコードだけを見る監視ではこのエラーを拾えません。error_codeフィールドをアプリケーション側で明示的に読む必要があります。
ログをerror_code単位で集計しておけば、url_not_in_prior_contextが増えたときに、どのリクエスト経路でURLが会話に載っていないかを後から特定しやすくなります。
max_usesを設定している場合は、失敗したフェッチも回数に数えられます。出どころ検証で弾かれた試行が、上限の枠を使い切る原因になることがあります。
症状から原因を切り分ける
エラーが出たときは、error_codeの値からURLの出どころを順にたどります。
url_not_in_prior_contextの切り分け
- 1
error_codeを確認する
web_fetch_tool_result_errorのerror_codeがurl_not_in_prior_contextであることを確かめます。url_not_allowedなら、出どころではなくドメイン設定や取得先の制限が原因です。 - 2
URLが会話のどこに載っているかを探す
リクエストの
messagesの中で、そのURLが文字列として現れるブロックを探します。ユーザーメッセージ、クライアントツールのtool_result、検索結果のどれにも無ければ、Claudeが推測したURLです。たとえば、ページ番号を?page=2のように類推してURLを組み立てた場合です。 - 3
前の表の右列に当たるか確かめる
システムプロンプトにだけ書かれたURLや、コード実行・MCPコネクタ・ツール検索の結果にだけ現れるURLは、前の表の「取得できない」側です。左列のどれかにURLを載せ直します。
web_searchを組み合わせると自動的に解決する
web_searchとweb_fetchの両方を有効にしている場合、ユーザーが「READMEを読んで」のようにURLを示さずに特定のページを指定すると、Claudeはまずweb_searchでそのページを探します。見つかった結果のURLを使ってweb_fetchを呼ぶため、URLが検索結果として会話に一度登場してから使われ、url_not_in_prior_contextには当たりません。
web_fetchだけを有効にした構成では、この「探す」手段がありません。ユーザーが具体的なURLを示さない使い方をするなら、web_searchを併用するかどうかがこのエラーの発生頻度を左右する設計判断になります。
両方のツールを渡すリクエストは次の形です。ツールごとにmax_usesを持つので、検索と取得の上限をそれぞれ決められます。ツール名はweb_searchとweb_fetchです。
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 4096,
"messages": [{
"role": "user",
"content": "quantum computingの最近の記事を探して、いちばん関連度の高い1本を詳しく分析して"
}],
"tools": [
{"type": "web_search_20250305", "name": "web_search", "max_uses": 3},
{"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 5}
]
}'web_fetch_20250910は基本のフェッチ版です。後続のweb_fetch_20260209以降はClaudeがコードで取得内容を絞り込む動的フィルタリングに対応し、最新はweb_fetch_20260318です。出どころ検証は、版を問わずURL validationの節に書かれた共通のルールです。
載せ直すならweb_searchとクライアントツールのどちらか
候補が複数あってどれを取るか決まっていないときはweb_searchの検索結果、自前のデータからURLを引けるときはクライアントツールのtool_resultが向きます。
なおweb_fetchと自作のクライアントツールを同じターンで同時に呼ぶ構成では、web_fetch自体の実行タイミングがずれる別の仕様が関わります。詳細はtool_useとpause_turnの違いにまとめました。
Claude CodeのWebFetchツールとは別物
Claude CodeにもWebFetchという名前のツールがありますが、これは本記事で扱うMessages APIのweb_fetchサーバーツールとは別の実装です。Claude CodeのWebFetchは、ローカルの権限システム(allow/denyのドメインルール)で制御されます。
同じ「Webフェッチ」という名前でも、動いている面(surface)が違えば挙動もエラーの出方も別物です。Claude Codeの権限ルールの書き方はClaude Code WebFetch権限ルールにまとめています。
クライアントツールの結果からURLを渡すときの注意
クライアントツールのtool_resultにURLを含めれば、そのURLは会話に入ったものとして扱われます。社内検索APIやドキュメント管理システムのAPIが候補URLを返す実装なら、それをtool_resultのcontentに含めるだけで、後続のweb_fetchはこのエラーを踏みません。web_searchを使えない場合や、社内ネットワーク限定のドキュメントを対象にしたい場合の代替手段になります。
注意点が1つあります。APIキーやパスワードのような認証情報を含むように見えるURLは、システムプロンプトかユーザーメッセージのテキストに現れない限り拒否されます。エラーコードはurl_not_in_prior_contextではなくurl_not_allowedです。ツール結果にだけ現れる認証情報は数えられないため、そのようなURLを取得させたいときはユーザーメッセージに含めます。
url_not_in_prior_context以外のエラーコードとの違い
Web Fetchのエラーコードは次の9種類で、いずれも同じweb_fetch_tool_result_errorの形式で返ります。
| エラーコード | 意味 |
|---|---|
invalid_tool_input | 意味不正なURL形式、またはhttp/https以外のスキーム |
url_too_long | 意味URLが最大長の250文字を超えている |
url_not_allowed | 意味ドメインフィルタ(組織の設定を含む)やAnthropic側の制限によるブロック。制限にはプライベートアドレス、robots.txt、提供していない認証情報を含むと見えるURLがある |
url_not_in_prior_context | 意味URLが会話の中に事前に登場していない |
url_not_accessible | 意味コンテンツの取得に失敗した(HTTPエラー) |
too_many_requests | 意味レート制限を超えた |
unsupported_content_type | 意味テキスト・HTML・PDF以外の形式 |
max_uses_exceeded | 意味フェッチ回数の上限に達した |
unavailable | 意味内部エラー |
この中でurl_not_in_prior_contextだけが、URLの形式や取得結果ではなく、URLが会話のどこに載っていたかを見る検証です。他のコードはURLそのもの、設定、取得先の応答のどれかに原因があります。
ほかのエラーコードも含めたハンドリングの設計は、Claude APIのエラーハンドリング設計も参照してください。
出どころ検証はツールのパラメータで切れない
基本版(web_fetch_20250910)のツール定義に並ぶパラメータは、max_uses、allowed_domains、blocked_domains、citations、max_content_tokensです。後の版ではuse_cache(20260309以降)とresponse_inclusion(20260318以降)が加わります。allowed_domainsとblocked_domainsは同時には指定できません。allowed_domainsの運用上の落とし穴はallowed_domainsをホモグラフ攻撃で回避される仕組みと対策で扱っています。
一方、基本版にも後の版にも、URLの出どころ検証を切り替えるパラメータはありません。Claudeにこのエラーを踏ませないためには、URLが会話に載るように、リクエストとツールの実装側で整える以外に手はありません。
出どころ検証を通ったあとの制約
URLが会話に載ってフェッチが通っても、取得できる内容には別の制約があります。JavaScriptで動的に描画されるサイトは、Web Fetchでは取得できません。ブラウザ操作が要るページには、アプリケーション側でブラウザを動かして結果をツール結果として返すブラウザ使用ツールが案内されています。
取得内容が大きいときは、max_content_tokensで上限を決めておけます。上限を超えるとツールが内容を切り詰めます。この上限はテキストに適用され、PDFなどのバイナリには適用されません。
公式が示すトークン数の目安は、平均的なWebページ(10 kB)で約2,500トークン、大きなドキュメントページ(100 kB)で約25,000トークン、論文PDF(500 kB)で約125,000トークンです。
まとめ
このエラーはHTTP 200の本体に入って返るので、監視はerror_codeで拾います。ユーザーが具体的なURLを示さない用途なら、web_searchを併用しておくと、Claudeが推測したURLをフェッチして弾かれる場面が減ります。
往復の実装を自分で書きたくない場合は、Tool RunnerやAdvanced Tool Useのツール群も検討候補になります。