Claude Media
Claude Consoleで組織のweb fetchを止めたときの400エラーとドメイン制限

Claude Consoleで組織のweb fetchを止めたときの400エラーとドメイン制限

管理者がConsoleのCapabilitiesでweb fetchをオフにすると、ツール付きのMessages APIは400になります。ドメイン制限の合成ルールと、Managed Agentsで挙動が変わる点を解説します。

昨日まで動いていたweb_fetch付きのリクエストが、突然 400 invalid_request_error で落ちる。コードも変えていないなら、組織の管理者がClaude ConsoleのCapabilitiesページでweb fetchをオフにした可能性があります。オフのままではツールを付けたリクエストが通らず、リトライしても直りません。

web fetchをオフにすると何が起きるか

組織の管理者は、Claude ConsoleのCapabilitiesページから、組織全体のweb fetchを止められます。オフの間は、web fetchツールを含むMessages APIのリクエストが 400 invalid_request_error で失敗します。エラーメッセージには、web fetchが有効になっていない旨が書かれます。

ここで見落としやすいのが、通常のツール失敗との違いです。web fetchが動いていて個別のURLで失敗するときは、APIは200を返し、レスポンス本文の web_fetch_tool_result_error にエラーコードが入ります。Claudeはそのエラーを受け取って、同じターンを続けます。組織設定でオフの場合は、リクエストそのものが400で拒否されるので、ターンが始まりません。

くらべる

エラーの出方は原因で変わる

リクエスト全体が失敗

組織設定でweb fetchがオフ

HTTPステータスは400で、invalid_request_error です。ツールを tools に含めた時点で拒否されるため、Claudeの応答は一切返りません。

結果の中でエラー

個別のURLが取得できない

HTTPステータスは200です。本文の web_fetch_tool_result_error に url_not_allowed や url_not_accessible などのコードが入り、Claudeが読んで続行します。

同じ仕組みはweb searchにもあります。管理者がweb searchを止めている場合も、ツールを含むリクエストは400になり、検索結果内のエラーコードではなく、web searchが有効でない旨のメッセージが返ります。web searchとweb fetchの両方を使うアプリでは、どちらの設定が原因かをメッセージで見分けることになります。

400の原因をどう切り分けるか

400は他の理由でも出ます。パラメータの綴りや、allowed_domains と blocked_domains の併用などです。組織設定が原因かどうかは、次の順で確かめると早く決着します。

切り分け

web fetch付きリクエストが400になったときの切り分け

  1. Qエラーメッセージに、web fetchが有効でない旨の記述があるか?
    答えがいいえのとき

    メッセージが別のパラメータやドメイン形式を指しているなら、リクエスト側の誤りです。次の節の合成ルールを確認します。

    答えがはい
  2. Qtools からweb fetchを外すと、同じリクエストは通るか?
    答えがいいえのとき

    web fetch以外が原因です。メッセージの指す箇所を直します。

    答えがはい

組織のCapabilitiesでweb fetchがオフ

自分で直せる設定ではありません。管理者に、ConsoleのCapabilitiesページでweb fetchをオンにしてもらいます。

コード側では、400を捕まえて「ツールなしで続行する」フォールバックを用意しておくと、管理者の設定変更でサービス全体が止まる事態を避けられます。以下は例です。メッセージ文字列の一致判定は表現が変わると外れるので、判定が外れたときも例外を握りつぶさず再送出する形にしています。

import anthropic
 
client = anthropic.Anthropic()
 
fetch_tool = {"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 5}
messages = [{"role": "user", "content": "https://example.com/article を要約して"}]
 
try:
    resp = client.messages.create(
        model="claude-opus-5-5",
        max_tokens=1024,
        messages=messages,
        tools=[fetch_tool],
    )
except anthropic.BadRequestError as e:
    if "web fetch" not in str(e).lower():
        raise  # web fetch以外の400は、そのまま呼び出し元へ
    # 組織設定でオフの可能性。ツールなしで続けるか、管理者へ通知する
    resp = client.messages.create(
        model="claude-opus-5-5",
        max_tokens=1024,
        messages=messages,
    )

ドメイン制限は組織とリクエストの両方に効く

web fetchがオンのとき、管理者は同じCapabilitiesページで、許可ドメインまたはブロックドメインも設定できます。リクエスト側の allowed_domains / blocked_domains はこの組織設定と組み合わさって働き、合成ルールは次のとおりです。

  • リクエストの allowed_domains は、組織の許可リストの部分集合でなければならない。外れる項目があると、APIが検証エラーを返す
  • リクエストの許可リストに、組織がブロックしているドメインが含まれると、競合する項目名つきの400で拒否される
  • 取得できないURLは、url_not_allowed のエラー結果になる。このコードは、ドメインのルール(組織設定を含む)とAnthropic側の制限の両方で使われる

つまりリクエスト側は、組織の許可範囲を絞る方向にしか使えません。広げようとすると400になります。

ドメイン指定の書式は、組織設定でも変わりません。

  • スキームは付けない。example.com と書く
  • サブドメインは自動で含まれる。example.com は docs.example.com も覆う
  • docs.example.com のようにサブドメインを指定すると、そのサブドメインだけに絞られる
  • web fetchはドメインだけで照合する。パスを含む項目はweb fetchのURLに一致しない
  • *.example.com のようなドメイン部のワイルドカードは使えない
  • allowed_domains と blocked_domains は同じリクエストで併用できない

落とし穴

Unicodeのドメイン名は制限をすり抜ける

キリル文字の а を使った аmazon.com は、見た目が amazon.com と同じでも別のドメインです。ホモグラフ攻撃でフィルターを回避されうるため、許可・ブロックの一覧にはASCIIだけのドメイン名を使い、既存の項目に非ASCIIが混ざっていないかも点検します。

url_not_allowed は、ドメイン制限以外の理由でも出ます。プライベートアドレス、robots.txt、提供していない認証情報を含むらしいURLなどです。このコードだけでは組織設定が原因とは断定できません。別の拒否理由として url_not_in_prior_context もあり、こちらは動的URLを拒む仕組みが原因です。

Managed Agentsでは400にならない

Claude Managed Agentsのセッションでも、組織のweb fetch設定は効きます。ただし失敗の出方が違います。

くらべる

Messages APIとManaged Agentsで挙動が違う

リクエストが400で拒否

Messages API

管理者がオフにすると、web fetch付きのリクエストは 400 invalid_request_error になります。

エラー結果を返してセッション継続

Managed Agentsのセッション

管理者がオフにすると、web_fetch の呼び出しがエージェントへエラー結果を返し、セッションは続きます。

組織がweb fetchのドメインを設定している場合、Managed Agentsでは、URLが組織のリストとエージェントごとのリストの両方を通る必要があります。リダイレクト先のURLも同じ扱いです。対象になったURLが除外されると、エージェントにエラー結果が返ります。agent.tool_result イベントは is_error: true になり、内容にエラーコード url_not_allowed が入ります。

Managed Agents側のリストには、Messages APIより厳しい決まりがあります。

項目Messages APIManaged Agents
1リストの上限Messages API記載なしManaged Agents1〜64件
項目の文字Messages APIUnicodeも受け付ける(非推奨)Managed AgentsASCIIのみ
web fetchのパスMessages API含めても一致しないManaged Agents含めると拒否される
空のリストMessages API記載なしManaged Agents拒否される。制限なしにするなら省略か null

マルチエージェントのセッションでは、allowed_domains は「関わる全リストが覆うホストだけ」に絞られ、blocked_domains は足し合わされます。許可リストに共通のドメインが無いと、ツールは残ったまま全呼び出しが url_not_allowed で失敗します。サブエージェントの許可リストは、セッションのエージェントの許可リストの内側に収めます。

管理者がオフにする理由と、全停止以外の選択肢

web fetchのドキュメントには、信頼できない入力と機密データをClaudeが同時に処理する環境でツールを有効にすると、データ流出のリスクがあると警告があります。Claudeが取得できるのは、会話に既に出たURL(ユーザーメッセージ、クライアント側ツールの結果、過去のweb searchやweb fetchの結果)だけで、自分の出力にしか現れないURLは取得できません。それでもリスクは残るため、対策としてツールを完全に無効にする案が挙がっています。組織全体のオフは、この最も強い選択肢にあたります。

全停止まで踏み込まない場合の手段は、ドキュメントに次のものが並んでいます。

  • max_uses で1リクエストあたりの取得回数を絞る
  • allowed_domains で既知の安全なドメインに限る
  • url_sources で、クライアント側ツールの結果をURLの出どころから外す

max_uses で取得回数を絞ると、トークン消費の見積もりも変わります。料金はClaude APIのweb fetch料金、キャッシュの扱いはuse_cacheでキャッシュを回避する方法で扱っています。

開発者側から見ると、組織のオフは突然の400として現れます。管理者に連絡するときは、上の代替策を添えて「オフではなくドメイン制限で運用できないか」を相談する余地があります。

使える環境と制約

web fetchはClaude API、Claude Platform on AWS、Google Cloud上のClaudeモデル(Anthropic管理)、Microsoft Foundryで提供されます。Foundryでも、Azureでホストされるデプロイは基本版の web_fetch_20250910(動的フィルタリングなし)だけが対象です。Anthropicがホストするデプロイは全バージョンに対応します。

ゼロデータ保持(ZDR)の適格性と allowed_callers の回避策は、Server toolsのページに記載があります。

Claude Code側でWebFetchを止めた場合との違い

組織のCapabilitiesで止めた場合は、APIが400を返します。Claude Code側の設定で止めた場合は、Claude Codeがツールを出さないだけで、APIのエラーにはなりません。どちらの設定が効いているかを取り違えると、直す場所を間違えます。

Claude CodeのWebFetchを止めるのは環境変数で、ドメインの許可はWebFetch権限ルールで設定します。Consoleの設定とは別の仕組みです。

まとめ

400の原因が組織設定かどうかは、メッセージにweb fetchの無効を示す記述があるか、ツールを外すと通るかで分かります。設定を変えられるのは管理者だけです。そのため、アプリ側では400のフォールバックと、管理者への連絡経路を先に決めておくと、原因の特定が短く済みます。ドメイン制限を使う場合は、リクエスト側の許可リストを組織の許可リストの内側に置くことが前提です。

この記事を共有:XはてブLinkedIn