Skip to content

401/Auth Failure: Check auth_mode First, Then Headers

What You'll Learn

  • Determine within 3 minutes whether 401 is blocked by Antigravity Tools auth middleware
  • Understand the "effective value" of the four proxy.auth_mode modes (especially auto) in your current configuration
  • Get requests through with the correct API Key Header (and avoid Header priority pitfalls)

Your Current Struggles

Your client receives a 401 Unauthorized error when calling the local reverse proxy:

  • Python/OpenAI SDK: throws AuthenticationError
  • curl: returns HTTP/1.1 401 Unauthorized
  • HTTP clients: response status code 401

What is 401/Auth Failure?

401 Unauthorized in Antigravity Tools most commonly means: the proxy has authentication enabled (determined by proxy.auth_mode), but the request either doesn't carry the correct API Key, or carries a higher-priority but mismatching Header, causing auth_middleware() to directly return 401.

First confirm whether "proxy is blocking you"

Upstream platforms may also return 401, but this FAQ only handles "401 caused by proxy authentication". You can quickly distinguish this with /healthz below.

Quick Troubleshooting (Follow This Order)

Step 1: Use /healthz to Determine "Whether Auth is Blocking You"

Whyall_except_health allows /healthz through but blocks other routes; this helps you quickly locate whether 401 comes from the proxy authentication layer.

bash
 # Without any auth Header
curl -i http://127.0.0.1:8045/healthz

You should see

  • When auth_mode=all_except_health (or auto with allow_lan_access=true): usually returns 200
  • When auth_mode=strict: returns 401

/healthz is GET at the routing layer

The proxy registers GET /healthz in routes (see src-tauri/src/proxy/server.rs).


Step 2: Confirm the "Effective Value" of auth_mode (Especially auto)

Whyauto is not an "independent policy"—it calculates the actual mode to execute based on allow_lan_access.

proxy.auth_modeAdditional ConditionEffective Mode
off-off
strict-strict
all_except_health-all_except_health
autoallow_lan_access=falseoff
autoallow_lan_access=trueall_except_health

You can check this in the GUI's API Proxy page: Allow LAN Access and Auth Mode.


Step 3: Confirm api_key is Not Empty and You're Using the Same Value

Why When auth is enabled, if proxy.api_key is empty, auth_middleware() will directly reject all requests and log an error.

text
Proxy auth is enabled but api_key is empty; denying request

You should see

  • In the API Proxy page, you can see a key starting with sk- (default value is auto-generated by ProxyConfig::default())
  • After clicking "Regenerate/Edit" and saving, external requests immediately validate with the new key (no restart needed)

Step 4: Try with the Simplest Header First (Don't Use Complex SDKs Yet)

Why The middleware reads Authorization first, then x-api-key, then x-goog-api-key. If you send multiple Headers at once and the first one is wrong, even if the later ones are correct, they won't be used.

bash
 # Recommended format: Authorization + Bearer
curl -i http://127.0.0.1:8045/v1/models \
  -H "Authorization: Bearer sk-REPLACE_WITH_YOUR_PROXY_API_KEY"

You should see: HTTP/1.1 200 OK (or at least no longer 401)

Proxy Authorization compatibility details

auth_middleware() strips the Authorization value once using the Bearer prefix; if there's no Bearer prefix, it uses the entire value as the key for comparison. Documentation still recommends Authorization: Bearer <key> (more compliant with common SDK conventions).

If you must use x-api-key:

bash
curl -i http://127.0.0.1:8045/v1/models \
  -H "x-api-key: sk-REPLACE_WITH_YOUR_PROXY_API_KEY"

Common Pitfalls (All Real Issues from Source Code)

SymptomReal CauseHow to Fix
auth_mode=auto, but localhost calls still get 401allow_lan_access=true causes auto to evaluate to all_except_healthDisable allow_lan_access, or make the client carry the key
You think "I clearly sent x-api-key", but still get 401Also sent a mismatching Authorization, middleware prioritizes thatRemove extra Headers, keep only one you're sure is correct
Authorization: Bearer<key> still gets 401Missing space after Bearer, cannot strip by Bearer prefixChange to Authorization: Bearer <key>
All requests get 401, logs show api_key is emptyproxy.api_key is emptyRegenerate/set a non-empty key in the GUI

Lesson Summary

  • First use /healthz to locate whether 401 comes from the proxy authentication layer
  • Then confirm auth_mode (especially auto's effective mode)
  • Finally send only one definitely correct Header for verification (avoid Header priority pitfalls)

Next Lesson Preview

In the next lesson, we'll learn 429/Quota Errors: Correct Expectations for Account Rotation & Misconceptions About Model Capacity Exhaustion.

You'll learn:

  • Whether 429 is "quota shortage" or "upstream rate limiting"
  • Correct expectations for account rotation (when it automatically switches and when it doesn't)
  • Use configuration to reduce 429 probability

Appendix: Source Code Reference

Click to expand source code locations

Updated: 2026-01-23

FeatureFile PathLine Numbers
ProxyAuthMode enumsrc-tauri/src/proxy/config.rs5-18
ProxyConfig: allow_lan_access/auth_mode/api_key and defaultssrc-tauri/src/proxy/config.rs174-258
auto mode parsing (effective_auth_mode)src-tauri/src/proxy/security.rs1-30
Auth middleware (Header extraction and priority, /healthz exemption, OPTIONS allow)src-tauri/src/proxy/middleware/auth.rs14-77
/healthz route registration and middleware ordersrc-tauri/src/proxy/server.rs170-193
Auth documentation (modes and client conventions)docs/proxy/auth.md1-45

Key Enums:

  • ProxyAuthMode::{Off, Strict, AllExceptHealth, Auto}: Authentication modes

Key Functions:

  • ProxySecurityConfig::effective_auth_mode(): Resolves auto to actual policy
  • auth_middleware(): Executes authentication (includes Header extraction order and /healthz exemption)