← All guides
Setup

Claude Code Proxy: Route It Through a Corporate Proxy or an LLM Gateway

Neo ZinoBy Neo Zino - builder of ClockedCode9 min read

Route Claude Code through a corporate proxy with HTTPS_PROXY and a custom CA, or through an LLM gateway with ANTHROPIC_BASE_URL. Tested setup and fixes.

Claude Code Proxy: Route It Through a Corporate Proxy or an LLM Gateway

Made with DispatchSEO

On this page

To run Claude Code through a proxy, export HTTPS_PROXY=http://proxy.example.com:8080 before you launch claude. If your company inspects TLS, also set NODE_EXTRA_CA_CERTS to its root certificate. If what you actually have is an LLM gateway, that is a different job: set ANTHROPIC_BASE_URL and a gateway credential instead. People search "claude code proxy" for both, and mixing the two variable families is the most common reason the setup doesn't work.

TL;DR: Corporate proxy: HTTPS_PROXY (plus NO_PROXY, plus NODE_EXTRA_CA_CERTS if TLS is inspected). Gateway: ANTHROPIC_BASE_URL plus ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY. Put them in the env block of ~/.claude/settings.json so background agents and new terminals pick them up. Verify with claude --debug and /status. SOCKS isn't supported.

Which kind of proxy do you have?

Ask one question: does the traffic still end up at Anthropic's API, or does it end up at something you or your employer runs?

Two meanings of "Claude Code proxy"

Corporate forward proxy

HTTPS_PROXY, NO_PROXY, NODE_EXTRA_CA_CERTS

  • The destination stays api.anthropic.com; the proxy only carries the connection
  • Your login or API key still authenticates against Anthropic
  • Typical symptom: timeouts, ENOTFOUND, or certificate errors on first launch
  • SOCKS proxies are not supported

LLM gateway (base URL)

ANTHROPIC_BASE_URL plus ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY

  • The destination becomes your gateway, which forwards to a provider
  • A gateway credential replaces the claude.ai login for those requests
  • Typical symptom: 401, 400 on unknown fields, or models missing from /model
  • Gateway must accept the Anthropic Messages format

Sourced from code.claude.com/docs/en/network-config and /llm-gateway-connect. Checked 2026-09-30.

If IT handed you a proxy hostname and port, you have the left column. If a platform team handed you a base URL and a key, you have the right one. Some setups need both: a corporate proxy that carries traffic to an internal gateway. They don't conflict, and the later sections set them independently.

Sending Claude Code through a corporate proxy

Claude Code reads the standard proxy variables. Set them before launch, because a running session doesn't pick up later shell changes:

export HTTPS_PROXY=https://proxy.example.com:8080
export HTTP_PROXY=http://proxy.example.com:8080
export NO_PROXY="localhost,192.168.1.1,example.com,.example.com"

A few details from the official network docs that save time:

  • Lowercase names work too, and Claude Code uses the first one set in the order https_proxy, HTTPS_PROXY, http_proxy, HTTP_PROXY.
  • NO_PROXY accepts space-separated or comma-separated lists, and * bypasses the proxy for everything.
  • Basic auth goes in the URL: http://username:password@proxy.example.com:8080. For NTLM or Kerberos, the docs point you to an LLM gateway that supports your auth method instead.
  • The proxy URL is the one setting checked at startup. If it can't be parsed, for example because it's missing the http:// scheme, launch stops with an error naming the variable.

Your proxy and firewall also need to allow the hosts Claude Code talks to. The required ones in the docs table are api.anthropic.com, claude.ai, platform.claude.com, and downloads.claude.ai for the native installer and updater. registry.npmjs.org matters if you install through npm or use npx-launched MCP servers.

Trusting your company's TLS certificate

A TLS-inspection proxy re-signs HTTPS traffic with the company's own CA. By default Claude Code trusts its bundled Mozilla CA set plus your operating system's certificate store, so if IT installed the root cert in the OS store, it often just works. On npm installs that needs Node 22.15 or later; the native installer always can read the OS store.

When it doesn't, point Claude Code at the bundle directly:

export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/corp-ca.pem

CLAUDE_CODE_CERT_STORE controls which sources are trusted. It takes a comma-separated list of bundled and system, and defaults to bundled,system. For proxies that demand a client certificate (mTLS), set CLAUDE_CODE_CLIENT_CERT, CLAUDE_CODE_CLIENT_KEY, and optionally CLAUDE_CODE_CLIENT_KEY_PASSPHRASE.

Claude Code doesn't validate most of these values when it reads them, so confirm they loaded:

claude --debug

Debug output goes to ~/.claude/debug/<session-id>.txt. The docs show lines like CA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (/etc/ssl/certs/corp-ca.pem) when the file loaded, and a Failed to read line with a reason when it didn't. Inside a session, /status has a Proxy row showing the active URL and flags one it couldn't parse as invalid and ignored.

Pointing Claude Code at a gateway instead

An LLM gateway (LiteLLM, Kong, a cloud API gateway, your platform team's service) sits between Claude Code and the model provider. You change the destination with ANTHROPIC_BASE_URL and supply a credential the gateway issued:

export ANTHROPIC_BASE_URL=https://llm-gateway.example.com
export ANTHROPIC_AUTH_TOKEN=sk-gateway-key

Which credential variable depends on what the gateway reads. ANTHROPIC_AUTH_TOKEN goes out as Authorization: Bearer, ANTHROPIC_API_KEY as x-api-key, and an apiKeyHelper script sends both. A credential in the wrong variable produces a 401. If you don't know which one, start with ANTHROPIC_AUTH_TOKEN.

Test the gateway with curl from the same shell before blaming Claude Code. This is the docs' own verification request:

curl -sS -w '\n%{http_code}\n' -X POST "$ANTHROPIC_BASE_URL/v1/messages" \
  -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model": "claude-sonnet-4-6", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'

A JSON body starting {"id":"msg_ means the URL and credential work. An "unknown model" error still proves both, because the gateway authenticated you before rejecting the model name.

Three behaviors catch people out:

  • Base URL alone doesn't switch billing. Without a credential variable or apiKeyHelper, a saved claude.ai login stays active and its limits still apply, even though requests route through the gateway.
  • Background traffic ignores the gateway. Version checks and telemetry still go to Anthropic. On an egress-locked network, add CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1, which also disables auto-updates.
  • Gateways that can't keep up with new features break. If a 400 names context_management or an unrecognized field, set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1.

For Bedrock, Vertex, or Foundry gateways there are provider-specific base URL variables such as ANTHROPIC_BEDROCK_BASE_URL paired with CLAUDE_CODE_SKIP_BEDROCK_AUTH=1. Use those only if your gateway team named the provider. If the curl test above returns JSON, you don't need them.

What a local logger caught on both paths

Docs tell you what should happen. I wanted to see what crosses the wire, so on 2026-09-30 I ran Claude Code 2.1.286 (claude -p "hi") twice against throwaway Node listeners on localhost: one faking a gateway that returns 401, one acting as a bare CONNECT proxy.

What each listener actually saw (Claude Code 2.1.286)

ANTHROPIC_BASE_URL=http://127.0.0.1:4011

Fake gateway that answers every request with 401

1
HEAD /api/hello probe
7
POST /v1/messages?beta=true (retries)
10
anthropic-beta flags per request

Bearer header from ANTHROPIC_AUTH_TOKEN, anthropic-version 2023-06-01, JSON body keys: model, messages, system, tools, metadata, max_tokens, thinking, context_management, output_config, stream.

HTTPS_PROXY=http://127.0.0.1:4012

Bare proxy that logs CONNECT and refuses it

1
CONNECT api.anthropic.com:443
0
requests to any other host

The proxy never saw a path or a header. It only learned the destination host and port, because the TLS tunnel hides the rest.

Measured 2026-09-30 with a throwaway Node listener on localhost. Retry count depends on timing and version.

Two things stood out. First, a gateway sees everything: the full Messages request, the auth header, ten anthropic-beta flags, and the body shape. That is the point of a gateway, and it is why you only point Claude Code at one you trust. Second, a forward proxy sees almost nothing. Because HTTPS is tunnelled, the proxy logged a single CONNECT api.anthropic.com:443 and no path, headers, or body. If your security team wants to audit prompts, a plain forward proxy won't do it without TLS inspection, which is exactly when you need the CA setup above.

The gateway also got a HEAD /api/hello probe before the first message, and Claude Code retried the failing request several times within the 60-second cap. A gateway that answers 401 slowly will look like a hang, not an error.

Making it stick in settings.json

Exports last for one terminal. Everything above can live in the env block of a settings file instead:

{
  "env": {
    "HTTPS_PROXY": "https://proxy.example.com:8080",
    "NO_PROXY": "localhost,127.0.0.1,.example.com",
    "NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/corp-ca.pem"
  }
}

The docs say this is the only reliable way to reach background agents: a per-user supervisor process hosts them, inherits the environment of whichever shell started it first, and may inherit nothing at all if it was installed as an OS service. A variable exported only in your shell reaches them by luck.

Keep credentials out of a project's .claude/settings.json, because that file is committed. Use ~/.claude/settings.json or .claude/settings.local.json. If both a shell export and the env block set a variable, the settings-file value wins. The settings.json generator writes a valid file if you'd rather not hand-edit JSON, and the permissions guide covers what else belongs in that file.

The VS Code extension is the exception: gateway variables go in VS Code's own claudeCode.environmentVariables setting, and the desktop app reads its own third-party inference configuration rather than settings.json.

Reading the error messages

Symptom, cause, fix

  • ConnectionRefused or ENOTFOUND

    Nothing answers at the proxy or base URL, or DNS can't resolve it

    Test the URL with curl from the same shell

  • SSL certificate verification failed / self-signed certificate

    A TLS-inspection proxy re-signs traffic with a CA Claude Code doesn't trust

    Set NODE_EXTRA_CA_CERTS to the CA bundle

  • 401 from the gateway

    Credential is in a header the gateway doesn't read

    Swap ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY

  • 400 naming context_management or "Extra inputs are not permitted"

    Upstream rejects fields Claude Code sends to Anthropic-format endpoints

    Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1

  • 403 HTML page, gateway logs show nothing

    A WAF in front of the gateway blocked the request body

    Exempt /v1/messages from body inspection

Sourced from code.claude.com/docs/en/llm-gateway-connect. Checked 2026-09-30.

The diagnostic order that works: test with curl first (it separates "my network" from "Claude Code"), then claude --debug to confirm your variables loaded, then /status to see which base URL and credential source are active. If curl succeeds but Claude Code asks you to log in, the usual cause is a credential set only in a project settings file, which applies after the first-run trust prompt. Move it to a shell export or ~/.claude/settings.json. If everything is slow rather than broken, see why Claude Code feels slow.

When a proxy is the wrong fix

  • You only want a different model. Anthropic doesn't support routing Claude Code to non-Claude models through a gateway. Community translation proxies exist (several top the search results), but you take on breakage each time Claude Code adds a request field.
  • You want cost tracking for one person. A gateway is infrastructure you run and keep updated. For a solo developer, it costs more than it saves.
  • Your proxy needs SOCKS. Not supported. Put an HTTP proxy in front, or use a gateway.
  • The real problem is DNS or a VPN. ENOTFOUND often means the machine can't resolve the host at all, and no proxy variable fixes that.

If you're setting up Claude Code for a team and want the rest of the config (permissions, hooks, a tuned CLAUDE.md) in one paste, that's what ClockedCode's master prompt is for.

FAQ

Does Claude Code support SOCKS proxies?

No. The official network docs state that Claude Code does not support SOCKS proxies. Use an HTTP or HTTPS proxy through HTTPS_PROXY, or put an HTTP gateway in front of the SOCKS tunnel.

What is the difference between HTTPS_PROXY and ANTHROPIC_BASE_URL?

HTTPS_PROXY sends Claude Code's traffic through a forward proxy while the destination stays api.anthropic.com. ANTHROPIC_BASE_URL changes the destination itself, so requests go to your LLM gateway instead.

Why does Claude Code fail with a certificate error behind my company proxy?

A TLS-inspection proxy re-signs traffic with your company's own certificate authority. If that root certificate isn't in the operating system store, Claude Code can't verify it. Set NODE_EXTRA_CA_CERTS to the path of the CA bundle and restart.

Do I need to put localhost in NO_PROXY?

Not for Claude Code's own WebSocket connections. The docs say it never sends those to localhost, ::1, or 127.0.0.0/8 through the proxy. Other local services you call from tools may still need a NO_PROXY entry.

Can I use Claude Code with a non-Claude model through a gateway?

Anthropic doesn't support routing Claude Code to non-Claude models through any gateway. A gateway has to expose a supported Claude API format, and translation layers that map other models onto it are unsupported territory.

Does setting ANTHROPIC_BASE_URL replace my claude.ai subscription?

Not on its own. Without a gateway credential variable or an apiKeyHelper, a saved claude.ai login stays the active credential and its limits still apply. Setting ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY makes the gateway credential win.