# WARP 출구 IP 갱신하기: Gemini 지역 미지원 오류를 좁혀 가는 방법

> Canonical: https://vxi.me/ko/posts/warp-egress-gemini-location-error/
> Locale: ko-kr
> Published: 2026-10-05
> Updated: 2026-10-05
> Markdown: https://vxi.me/ko/posts/warp-egress-gemini-location-error.md

Google / Gemini 트래픽만 Cloudflare WARP로 분리해서 보내다 보면 꽤 헷갈리는 장애를 만날 수 있습니다. WARP 상태는 분명 `Connected`이고 웹페이지도 정상적으로 열리는데 특정 Gemini API 또는 클라이언트만 갑자기 다음 오류를 반환합니다.

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

제가 겪었던 상황도 이랬습니다. 더 혼란스러웠던 점은 Gemini 웹은 정상인데 Gemini backend를 사용하는 다른 클라이언트만 실패했다는 것입니다.

이런 상황에서 가장 먼저 “계정이 막혔나”, “Xray routing이 깨졌나”, “Nginx를 다시 설정해야 하나”라고 생각하기 쉽습니다. 하지만 실제로 가장 효과적이었던 첫 행동은 훨씬 작았습니다.

**Gemini가 실제로 보고 있는 WARP egress를 확인하고, WARP를 재연결한 뒤, 연결 전후의 egress가 어떻게 달라졌는지 비교하는 것**입니다.

여기서 가정하는 구조는 server의 WARP가 local SOCKS5 proxy로 동작하고, Xray가 특정 Google / Gemini TCP 트래픽만 이 SOCKS5로 보내는 형태입니다. inbound는 Cloudflare + Nginx + VLESS/WS일 수 있지만 **입구와 출구는 서로 다른 문제**입니다.

## 먼저 VPS IP가 아니라 마지막 WARP egress를 본다

저는 먼저 전체 path를 단순하게 그립니다.

```text
클라이언트
  ↓
Cloudflare / Nginx / Xray
  ↓
Google / Gemini 트래픽
  ↓
127.0.0.1:40000
  ↓
Cloudflare WARP
  ↓
Gemini
```

여기서 가장 자주 잘못 보는 값은 VPS의 origin IP입니다. 그것은 서버 자체의 public IP일 뿐입니다. Gemini 트래픽이 Xray에서 WARP로 들어갔다면 Google이 최종적으로 보게 되는 값은 VPS native egress가 아니라 **WARP egress**여야 합니다.

Cloudflare의 WARP Local proxy 방식도 같은 구조입니다. 명시적으로 HTTPS 또는 SOCKS5 local proxy를 사용하도록 설정한 application traffic만 WARP를 통과하고, 나머지 트래픽은 일반 네트워크 경로를 사용할 수 있습니다.

그래서 장애를 볼 때 브라우저나 VPS public IP만 확인하거나 `warp-cli status`만 보는 것보다 **실제 SOCKS5를 통과한 request를 직접 테스트하는 편이 정확**합니다.

먼저 현재 egress를 기록합니다.

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

정상이라면 대략 다음과 같은 값을 봅니다.

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

세 필드는 의미가 조금씩 다릅니다.

- `warp=on`: 이 request가 실제로 WARP를 통과했음을 보여 줌
- `ip=`: destination이 실제로 본 egress address
- `loc=`: 지역 방향을 판단하는 참고 정보

여기서 `loc=US` 또는 `loc=CA`가 나왔다고 해서 “이 client가 반드시 허용된다”고 단정하면 안 됩니다.

Google AI Developers Forum에도 server가 Gemini 지원 지역에 있고 외부 geolocation database도 정상으로 보이는데 API가 여전히 같은 `User location is not supported` 오류를 반환하는 사례가 보고된 적이 있습니다. 그래서 `loc`은 방향을 좁히는 힌트이지 최종적인 서비스 eligibility 판정은 아닙니다.

## 제가 쓴 복구 순서는 기록 → 재연결 → 다시 비교였다

WARP 자체가 건강하고 오류 메시지가 location / eligibility를 가리킨다면 처음부터 Xray, Nginx, Cloudflare inbound를 동시에 바꾸지 않습니다.

가장 작은 변화부터 줍니다.

```bash
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)='
```

제가 실제로 겪었던 장애에서는 reconnect 전후로 서로 다른 shared egress가 할당됐고 `warp=on`은 유지됐습니다. 이후 문제였던 클라이언트를 다시 테스트했을 때 location 오류가 사라졌습니다.

이 결과가 의미하는 것은 **이전 WARP egress가 장애의 trigger 중 하나였다는 것** 정도입니다. 특정 WARP IP가 영구적으로 문제가 있다거나 Gemini 내부 geolocation / risk classification 규칙을 역으로 알 수 있다는 뜻은 아닙니다.

디버깅에서는 “전체 proxy chain 문제”에서 “마지막 egress 쪽 문제”로 범위를 좁혔다는 것만으로도 충분히 가치가 있습니다.

reconnect 뒤 IP가 그대로라면 한 번 더 시도할 수 있지만 다음 명령을 일반적인 IP rotation 방법으로 사용하지는 않습니다.

```bash
warp-cli registration delete
warp-cli registration new
```

registration identity와 shared public egress는 1:1 관계가 아닙니다. registration을 삭제하고 새로 만들어도 새 egress가 보장되지 않으며, 오히려 정상적인 WARP registration state까지 다시 변수로 만들 수 있습니다.

production node에서는 이 비용이 보통 더 큽니다.

제가 유지하는 순서는 다음과 같습니다.

```text
WARP SOCKS5 정상 여부 확인
        ↓
ip / loc / warp 기록
        ↓
disconnect / connect
        ↓
egress 다시 기록
        ↓
egress 변화 → Gemini / client 재테스트
        ↓
여전히 실패 → routing, IPv4/IPv6, DNS, upstream classification 점검
```

이 순서의 장점은 한 번에 하나의 변수만 바꾼다는 것입니다.

이미 inbound가 안정적으로 동작하고 있다면 `FAILED_PRECONDITION` 하나 때문에 Nginx, VLESS, Cloudflare DNS, Xray routing을 동시에 수정하지 않는 편이 좋습니다. 변경을 많이 할수록 무엇이 실제 복구 원인이었는지 알기 어려워집니다.

## 일반 WARP를 고정 residential proxy처럼 생각하면 안 된다

또 하나 분명히 해야 할 경계가 있습니다.

일반 WARP는 사용자가 원하는 국가나 도시, 특정 public IP를 선택하는 residential proxy pool이 아닙니다. Cloudflare는 WARP를 “다른 국가에서 접속한 것처럼 보이게 하기 위한 제품”으로 설명하지 않습니다.

disconnect / reconnect로 shared egress가 바뀌는지 관찰할 수는 있지만 이것을 **결정적인 IP rotation capability**로 가정하면 안 됩니다.

업무상 고정되고 독점적이며 allowlist에 넣을 수 있는 egress가 정말 필요하다면 Cloudflare Zero Trust Enterprise의 Dedicated Egress IP 같은 별도 제품 계층을 봐야 합니다. 이것은 account 전용 static egress이고 특정 Cloudflare data center에 연결됩니다. 일반 WARP shared egress와는 성격이 다릅니다.

개인 개발자가 Gemini의 일시적인 classification 문제 때문에 바로 이 단계까지 갈 필요는 없는 경우가 많습니다. 다만 “안정적인 고정 egress가 필요할 때 어느 계층에서 해결해야 하는가”를 구분하는 데 도움이 됩니다.

저는 이 문제를 결국 두 종류로 나눠 봅니다.

- WARP SOCKS5 자체가 안 됨 → WARP service / local proxy 문제
- SOCKS5는 정상이고 `warp=on`인데 Gemini location error → egress address, protocol path, upstream classification에 집중

이렇게 나누면 이미 정상인 inbound까지 다시 만들 필요가 없습니다.

여러 AI 도구를 직접 관리하는 proxy layer에 연결하고 있다면 [Codex를 CLIProxyAPI로 프록시하는 방법: Docker 배포, OAuth 로그인, 클라이언트 설정](/ko/posts/cliproxyapi-codex-docker-proxy/)도 이어서 볼 수 있습니다. 그 글이 통합 AI access layer에 가깝다면 이 글은 **traffic을 이미 WARP로 분리한 뒤 문제가 생겼을 때 범위를 빠르게 줄이는 방법**에 가깝습니다.
