Google / Gemini 系の通信だけを Cloudflare WARP に流していると、少し分かりにくい障害に当たることがあります。WARP 自体は Connected のまま、ブラウザでは普通にアクセスできるのに、Gemini API や一部クライアントだけが突然こう返すケースです。

HTTP 400
FAILED_PRECONDITION
User location is not supported for the API use.

私が遭遇したときも同じでした。ややこしかったのは、Gemini の Web 版は正常だったことです。問題が出ていたのは Gemini のバックエンドを使う別クライアントだけでした。

こういうとき、最初は「アカウント制限か」「Xray のルーティングが壊れたか」「Nginx を組み直すべきか」と考えがちです。ですが、実際に最初に確認すべきなのはもっと単純でした。Gemini から見えている実際の WARP 出口を確認し、WARP を再接続して、前後で出口が変わるかを見ることです。

ここで想定している構成は、サーバー上の WARP をローカル SOCKS5 として動かし、Xray から Google / Gemini 向けの TCP 通信だけをその SOCKS5 に流す形です。入口側が Cloudflare + Nginx + VLESS/WS でも、入口と出口は別の問題として考えた方が切り分けやすくなります。

見るべきなのは VPS の IP ではなく、最後の WARP 出口

私はまず通信経路を次のように整理します。

クライアント
  ↓
Cloudflare / Nginx / Xray
  ↓
Google / Gemini 向け通信
  ↓
127.0.0.1:40000
  ↓
Cloudflare WARP
  ↓
Gemini

ここで混同しやすいのが VPS の Origin IP です。これはサーバー自身の公開 IP にすぎません。Gemini 向け通信が Xray から WARP に入っているなら、Google 側が最終的に見るのは VPS の生 IP ではなく WARP の出口です。

Cloudflare の WARP Local proxy も同じ考え方で、HTTPS / SOCKS5 のローカルプロキシへ明示的に設定されたアプリ通信だけが WARP を通ります。それ以外の通信は通常のネットワーク経路を使います。

そのため、障害調査ではブラウザや VPS 自身の IP ではなく、SOCKS5 経由で直接確認する方が確実です。

curl -s --socks5-hostname 127.0.0.1:40000 \
  https://www.cloudflare.com/cdn-cgi/trace \
  | grep -E '^(ip|loc|warp)='

正常なら、例えば次のような結果になります。

ip=<warp-egress-ip>
loc=US
warp=on

この三つは意味が違います。

  • warp=on は、そのリクエストが WARP を通ったことを示します。
  • ip= は相手側から実際に見えている出口 IP です。今回の切り分けではこれが最重要です。
  • loc= は地域の手掛かりですが、「この Gemini クライアントで必ず許可される」ことを保証するものではありません。

この最後の点は重要です。2026 年には Google AI Developers Forum でも、Gemini が利用可能な地域に VPS があり、外部の GeoIP 判定も正常なのに、Gemini API が User location is not supported を返したという報告がありました。

そのため loc=US や loc=CA は方向を確認する材料にはなりますが、最終判定そのものではありません。

私が使った復旧手順:記録して、再接続して、比較する

WARP の SOCKS5 自体は動いていて、エラーが location / eligibility に明確に寄っているなら、私は最初から Xray や Nginx、Cloudflare の入口設定を触りません。

まず変更点を一つに絞って、WARP を再接続します。

echo "=== BEFORE ==="
curl -s --socks5-hostname 127.0.0.1:40000 \
  https://www.cloudflare.com/cdn-cgi/trace \
  | grep -E '^(ip|loc|warp)='

warp-cli --accept-tos disconnect
sleep 5
warp-cli --accept-tos connect
sleep 10

echo "=== AFTER ==="
curl -s --socks5-hostname 127.0.0.1:40000 \
  https://www.cloudflare.com/cdn-cgi/trace \
  | grep -E '^(ip|loc|warp)='

今回の実例では、WARP の再接続前後で共有出口 IP が変わりました。warp=on は維持され、地域フィールドもサポート対象のままでした。その状態でクライアントを再テストすると、元の地域エラーは消えました。

ここから言えるのは、以前の WARP 出口がトリガーの一つだったということまでです。「特定の WARP IP は永久に問題がある」と断定できるわけではありませんし、Gemini 内部のリスク判定や GeoIP 分類ルールまで推測するべきでもありません。

ただ、障害範囲を「プロキシ全体」から「最後の出口」に絞れたというだけでも、実運用では十分価値があります。

再接続しても IP が変わらない場合はもう一度試すことはありますが、私は次のコマンドを通常の IP ローテーション手段としては使いません。

warp-cli registration delete
warp-cli registration new

WARP の登録情報と共有出口 IP は 1 対 1 ではありません。登録を削除して作り直しても、必ず新しい出口になるわけではありませんし、正常だった WARP の登録状態まで変数にしてしまいます。

運用中のノードなら、まずは次の順番で十分です。

WARP SOCKS5 が使えることを確認
        ↓
ip / loc / warp を記録
        ↓
disconnect / connect
        ↓
もう一度出口を記録
        ↓
出口が変化 → Gemini / クライアントを再テスト
        ↓
まだ失敗 → ルーティング、IPv4/IPv6、DNS、上流側分類を確認

ポイントは、一度に変更する変数を増やさないことです。入口側が正常に動いているのに、FAILED_PRECONDITION 一つを見て Nginx、VLESS、Cloudflare DNS、Xray のルールまで全部触ると、何が原因だったのか分からなくなります。

もう一つ境界をはっきりさせておくと、通常の WARP は「自由に国や都市を選べる住宅プロキシプール」ではありません。Cloudflare も、WARP は別の国から接続しているように見せる用途ではないと説明しています。

切断・再接続で共有出口が変わることはありますが、それを確定的な IP ローテーション機能として扱うのは危険です。

固定・専有・ホワイトリスト登録可能な出口が本当に必要なら、Cloudflare が別製品として提供している Zero Trust Enterprise の Dedicated Egress IP を検討する層になります。これはアカウント専用の静的出口で、通常の WARP 共有出口とは性質が違います。

個人開発者が Gemini の一時的な分類問題だけでここまで上げる必要は通常ありませんが、「固定出口を安定させたい」という要件は WARP の再接続ではなく、この製品層で解決すべきだと分かります。

私はこの種の障害を二つに分けています。WARP SOCKS5 自体が通らないなら、WARP サービスかローカルプロキシの問題。SOCKS5 は正常で warp=on なのに Gemini が location エラーを返すなら、出口 IP、プロトコル経路、上流側の分類を先に見ます。

複数の AI ツールを自分のプロキシ層にまとめているなら、CLIProxyAPI 経由で Codex を使う構成 も関連します。そちらは AI 接続入口を統一する話で、この記事は出口側で障害が起きたときの切り分けに寄せています。

関連資料