Skip to content

Proxy and VPN Configuration

Claude Code runs behind a corporate proxy once HTTPS_PROXY, plus NO_PROXY for exceptions, sits in the env block of a settings file. A TLS-inspecting proxy also needs its root certificate in the OS trust store or in NODE_EXTRA_CA_CERTS, and mTLS needs a client certificate and key. The firewall must allow api.anthropic.com, the sign-in hosts, and each feature’s hosts.

This page is for the developer whose first claude session fails on the corporate network, and for the platform engineer who has to make it work for the whole team. The usual picture: Claude Code works at home, but in the office it reports Unable to connect to API or SSL certificate verification failed. IT says “everything goes through Zscaler”, and the fix that worked on one laptop never reaches the background agents or the next hire.

What you’ll walk away with from corporate network setup

Section titled “What you’ll walk away with from corporate network setup”
  • A decision table that tells you which of the proxy, certificate, and mTLS settings your network needs
  • A settings.json env block that reaches every session, including background agents
  • The current host allowlist for Claude Code, split into required and optional hosts
  • A managed-settings file that ships the same configuration to every machine
  • A verification routine (claude --debug, /status, claude doctor) that proves the configuration loaded
  • A failure table that maps each error message to its cause and its fix

Every variable, host, and error message on this page was checked against the Claude Code network configuration, environment variable, and error reference pages and the installed CLI, version 2.1.283, on 2026-09-26.

Ask IT three questions before you touch a config file: is there a proxy, does it inspect TLS, and does the gateway demand a client certificate? The answers map to settings like this:

Your networkWhat to setSection
Direct internet access, or a split-tunnel VPN that does not route Anthropic hostsNothing—
An HTTP or HTTPS proxy is requiredHTTPS_PROXY, NO_PROXYPoint Claude Code at the proxy
The proxy decrypts TLS (Zscaler, Netskope, Palo Alto, Blue Coat, and similar)Nothing if the root CA is in the OS trust store; otherwise NODE_EXTRA_CA_CERTSTrust the proxy certificate
The gateway requires a client certificateCLAUDE_CODE_CLIENT_CERT, CLAUDE_CODE_CLIENT_KEYmTLS
The proxy only accepts NTLM or KerberosAn LLM gateway or a local authenticating proxyAuthenticated proxies
Only a SOCKS proxy existsNot supported by Claude Code (checked on v2.1.283); ask for an HTTP proxy or an LLM gateway—
Firewall with an egress allowlistThe hosts in the allowlist table—

Claude Code reads its network variables once, at startup. Put them in a settings file rather than a shell profile. A shell export reaches the terminal you launched from, but background agents run under a separate supervisor process that may never see that shell. The env block of ~/.claude/settings.json reaches every session.

  1. Get the proxy URL from IT, including the scheme. Claude Code refuses to launch when it cannot parse the proxy URL, for example proxy.company.com:8080 without http://, and names the variable to fix.

  2. Add the proxy to ~/.claude/settings.json:

    {
    "env": {
    "HTTPS_PROXY": "http://proxy.company.com:8080",
    "NO_PROXY": "localhost,127.0.0.1,.company.internal"
    }
    }

    HTTPS_PROXY is the recommended variable. Set HTTP_PROXY only when IT gives you no HTTPS proxy. Lowercase names work too, and Claude Code uses the first one it finds in the order https_proxy, HTTPS_PROXY, http_proxy, HTTP_PROXY. A stale lowercase value in your shell therefore wins over a correct uppercase one.

  3. Set NO_PROXY for internal hosts that must not go through the proxy, such as an internal MCP server or package mirror. It accepts comma- or space-separated lists, a leading dot for subdomains (.company.internal), and * to bypass the proxy for everything. You do not need a loopback entry for Claude Code’s own WebSocket connections: they never go through the proxy.

  4. Start a new session with claude. Running sessions do not pick up the change.

To try the proxy without editing a file, export the same variables in your shell and run claude. Move them into settings once they work.

Basic authentication works through the URL: http://USERNAME:PASSWORD@proxy.company.com:8080. Keep that value in ~/.claude/settings.json or managed settings, never in the repository’s .claude/settings.json, which is committed to git.

Claude Code has no built-in NTLM or Kerberos support. The Claude Code documentation recommends an LLM gateway that speaks your authentication method. The other common option is a local authenticating proxy such as Px or Cntlm, which authenticates upstream with your Windows or Active Directory credentials and exposes a plain proxy on localhost that you put in HTTPS_PROXY. A gateway is the better choice for a team: one service to maintain instead of a shim on every laptop.

A TLS-inspecting proxy re-signs every HTTPS connection with the company’s own root certificate. Claude Code rejects that certificate unless it trusts the root.

By default, Claude Code trusts both its bundled Mozilla CA set and the operating system’s certificate store (CLAUDE_CODE_CERT_STORE defaults to bundled,system). If IT has already pushed the corporate root into the OS trust store, which most managed laptops have, Claude Code works without any certificate setting. There is one condition: reading the OS store needs a runtime with tls.getCACertificates. The native installer always has it; npm installs need Node 22.15 or later. On an older Node, only the bundled set and NODE_EXTRA_CA_CERTS apply, which is a common reason one developer’s machine fails while the next one works.

When the root is not in the OS store, or you run on an older Node, point Claude Code at a PEM file:

{
"env": {
"NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/corp-root-ca.pem"
}
}

To get the PEM file, ask IT for the root and any intermediate certificates, or export them yourself:

Terminal window
# macOS: export the corporate root by its name in Keychain Access
security find-certificate -a -c "Corp Root CA" -p /Library/Keychains/System.keychain > ~/corp-root-ca.pem
# Any OS: see which issuer the proxy presents for the API host
openssl s_client -connect api.anthropic.com:443 -proxy proxy.company.com:8080 -showcerts </dev/null 2>/dev/null | grep -E "s:|i:"

Replace Corp Root CA with the name of your company’s root certificate. If the openssl output shows your company as the issuer instead of a public CA, the proxy inspects TLS and you need this section.

NODE_EXTRA_CA_CERTS adds certificates; it does not replace the bundled set. Set CLAUDE_CODE_CERT_STORE=system only when policy says Claude Code must trust nothing beyond the OS store.

NODE_EXTRA_CA_CERTS handles server trust. When the gateway also requires Claude Code to prove its identity, add the client certificate and key:

{
"env": {
"CLAUDE_CODE_CLIENT_CERT": "/etc/pki/claude/client-cert.pem",
"CLAUDE_CODE_CLIENT_KEY": "/etc/pki/claude/client-key.pem"
}
}

If the key is encrypted, set CLAUDE_CODE_CLIENT_KEY_PASSPHRASE as well, and deliver it from a secret store rather than a file in a repository.

Certificate rotation needs no restart. To rotate, replace the files at the same paths. Since v2.1.232, Claude Code re-reads both files when a request fails with a connection reset or a TLS handshake error, and retries with the new pair. It does not re-read when the gateway completes the handshake and answers with an HTTP error, and OpenTelemetry exporters keep their first certificate until you restart. To confirm a rotation, start the session with claude --debug and look in the debug log for Stale connection — reloaded rotated mTLS client material. The line is absent when the pair was reloaded while applying settings, so a missing line alone is not a failure. Replace the pair before the old one expires.

Allow these hosts through the proxy and firewall. The table is the Claude Code documentation’s list on 2026-09-26, grouped by what breaks without each host.

HostNeeded forIf blocked
api.anthropic.comModel requests, the WebFetch domain safety check, feature flags, telemetry eventsNothing works
platform.claude.comSign-in and OAuth token refresh, for Console and claude.ai accountsCannot sign in
claude.ai, claude.comclaude.ai account sign-inCannot sign in with a claude.ai account
downloads.claude.aiNative installer, auto-updates, plugin executablesNo install or updates
registry.npmjs.orgnpm installs, npx-launched MCP servers, plugin dependenciesMCP servers and plugins fail to start
github.comPlugin marketplaces, including the official one/plugin installs fail
mcp-proxy.anthropic.comMCP connectors from claude.aiConnectors missing
storage.googleapis.comPlugin install counts in /pluginCosmetic
raw.githubusercontent.com/release-notes changelogCosmetic
code.claude.comBuilt-in documentation lookupsClaude cannot read its own docs
bridge.claudeusercontent.comClaude in Chrome extensionChrome extension cannot connect
*.frame.claudeusercontent.comReading artifact content, only when the Artifact tool is available for your accountClaude cannot open artifacts; CLAUDE_CODE_DISABLE_ARTIFACT=1 turns the tool off and drops the host
http-intake.logs.us5.datadoghq.com, browser-intake-us5-datadoghq.comOptional operational telemetry and error reports (direct Anthropic API only)Nothing breaks
formulae.brew.shUpdate checks on Homebrew installsNo update notice
*-review.googlesource.comGerrit change lookup, only for Claude Desktop Code tab sessions on googlesource.com checkoutsNothing breaks (optional)

Older guides, including an earlier version of this page, list statsig.anthropic.com and sentry.io. Neither host is on the list for v2.1.283: feature flags and telemetry events now go to api.anthropic.com, and the optional telemetry goes to the two Datadog hosts. To drop the optional hosts entirely, set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1. It also turns off auto-updates, /feedback, release notes, the fast mode availability check, and feature-flag fetching (which makes Remote Control unavailable), so decide it deliberately. The variable is unusual: 0 or false still disables the traffic, so unset it to turn the traffic back on.

If you use Amazon Bedrock, Google Cloud’s Agent Platform (formerly Vertex AI), Microsoft Foundry, or an LLM gateway, model traffic goes to that provider instead. WebFetch still calls api.anthropic.com for its domain safety check unless you set skipWebFetchPreflight: true in settings, and the fast mode availability check also calls api.anthropic.com through your proxy rather than the gateway. See LLM gateway configuration for the provider side.

Make background agents use the same network settings

Section titled “Make background agents use the same network settings”

Background agents started with claude --bg, claude agents, or /background run under one per-user supervisor process. The supervisor inherits the environment of whichever shell started it first. If your proxy lives only in ~/.zshrc, background agents work when that shell happened to start the supervisor and fail silently when an IDE terminal did.

The fix is the one from the first section: put every network variable in the env block of ~/.claude/settings.json or managed settings. After changing it, stop the running supervisor so the next background session picks up the change:

Terminal window
claude daemon stop --any

claude daemon stop also terminates the background sessions it hosts, so let running agents finish first or tell the team before you run it on a shared machine.

A split-tunnel VPN routes only corporate address ranges through the tunnel. Claude Code’s hosts use the public internet, so you usually need no settings at all.

A full-tunnel VPN sends everything through corporate infrastructure. Expect all three: a proxy, TLS inspection, and corporate DNS. Configure them with the sections above. Two VPN-specific problems show up in the error reference: WSL can inherit an unreachable nameserver in /etc/resolv.conf, and on macOS a disconnected or uninstalled VPN client can leave a stale utun interface or routing rule behind.

Roll the configuration out to the whole team

Section titled “Roll the configuration out to the whole team”

One developer fixing their own laptop does not scale. Ship the network block as managed settings so it applies to every session on every machine and ranks above user and project settings:

{
"env": {
"HTTPS_PROXY": "http://proxy.company.com:8080",
"NO_PROXY": "localhost,127.0.0.1,.company.internal",
"NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/corp-root-ca.pem"
}
}

Save it as its own drop-in file, managed-settings.d/20-network.json, next to managed-settings.json in the system directory. The platform team then owns the network block without editing the file that the security team owns. Claude Code merges managed-settings.json first and then every *.json file in managed-settings.d/ in alphabetical order, and it merges env blocks key by key. The system directories are:

  • macOS: /Library/Application Support/ClaudeCode/
  • Linux and WSL: /etc/claude-code/
  • Windows: C:\Program Files\ClaudeCode\

Two traps make a correct file do nothing, or worse:

  • Another managed source wins. By default (managedSourcesBehavior: "first-wins"), Claude Code uses the highest-ranked managed source and ignores the rest: server-managed settings from claude.ai first, then MDM or registry policy, then these files. If your organization already pushes a policy through the claude.ai console or MDM, put the network block there instead. /status names the managed source in use and the ones it skipped.
  • Invalid JSON stops every session. A managed file that does not parse as a JSON object makes Claude Code refuse to start, with an error that names the file. Validate the file with jq . 20-network.json in the pipeline that ships it.

Deliver the certificate file to the same path on every machine with the tooling that already places files on your fleet, or the setting points at nothing. For MDM profiles, server-managed settings, and the rest of the baseline policy, see enterprise integration. For containers, bake the same values into the image; the dev container guide covers that and its default-deny firewall.

Verify the network configuration without guessing

Section titled “Verify the network configuration without guessing”

Claude Code validates only the proxy URL at startup. A wrong certificate path shows up later, as a failed request. Prove each piece loaded instead of waiting for the failure.

  1. Start a session with debug logging written to a known file:

    Terminal window
    claude --debug-file /tmp/claude-net.log

    Without --debug-file, claude --debug writes to ~/.claude/debug/<session-id>.txt, not the terminal.

  2. Search the log for the lines that confirm each file loaded:

    Terminal window
    grep -E "CA certs:|mTLS:|Failed to (read|load)" /tmp/claude-net.log

    A working setup prints CA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (...) and, with mTLS, mTLS: Loaded client certificate from CLAUDE_CODE_CLIENT_CERT and the matching key line. A Failed to read or Failed to load line gives the reason.

  3. In the session, run /status. Check that it names the managed source you shipped. The Proxy row shows the active proxy URL and flags an unparseable value. The mTLS client cert and mTLS client key rows appear only when the files loaded. The Additional CA cert(s) row shows the path without checking the file, so trust the debug log for that one.

  4. Run claude doctor from a terminal for an installation and settings health check.

  5. Send one real prompt, such as Reply with OK. A reply proves the whole path: proxy, trust, and allowlist.

For a fleet, the platform team runs these steps on a canary machine after every change to the managed network block and signs off before the change reaches everyone. Developers run them only when a support ticket arrives.

These prompts need a working session, so run them on a machine that already connects: a home network, a colleague’s configured laptop, or a session that reaches the model through your gateway.

When the corporate network breaks Claude Code

Section titled “When the corporate network breaks Claude Code”
What you seeLikely causeRecovery
Unable to connect to Anthropic services at first run, with A proxy is configured via HTTPS_PROXYThe proxy blocks api.anthropic.com or platform.claude.comAsk IT to allow both hosts; test with curl -I https://api.anthropic.com from the same shell
Connection refused — a firewall or proxy may be blocking itNo proxy set on a network that requires one, or a wrong proxy portSet HTTPS_PROXY; confirm the host and port with curl -x http://proxy.company.com:8080 -I https://api.anthropic.com
Couldn't connect through your proxy (ERR_PROXY_TUNNEL)The proxy rejected the tunnel: wrong credentials or the host is not allowedFix the credentials in the URL, or ask IT to allow the host
SSL certificate verification failed (UNABLE_TO_GET_ISSUER_CERT_LOCALLY) or Self-signed certificate detected (SELF_SIGNED_CERT_IN_CHAIN)TLS inspection with a root Claude Code does not trustAdd the root to the OS store or set NODE_EXTRA_CA_CERTS; on npm installs, check that Node is 22.15 or later
Claude Code will not launch and names a proxy variableThe proxy URL cannot be parsed, often a missing http://Add the scheme
curl works but Claude Code does notA leftover ANTHROPIC_BASE_URL pointing at a gateway that is not running, or a lowercase https_proxy shadowing the right valueRun echo $ANTHROPIC_BASE_URL, check settings env blocks, and unset stale lowercase variables
Interactive sessions work, background agents do notNetwork variables exist only in a shell profileMove them to ~/.claude/settings.json, then run claude daemon stop --any
Streaming response ended before any complete data was received. Retrying without streaming.The proxy consumes or rewrites the streaming response body, so each request is sent twiceAsk IT to pass streaming response bodies and their headers through unmodified for the API host
Claude Code refuses to start and names a managed settings fileThe managed file is not valid JSONFix the file on the machine, then add a jq check to the pipeline that ships it
The managed network block is on disk but /status shows no proxyA higher-ranked managed source (claude.ai console or MDM) wins under first-winsMove the env block into that source, or review managedSourcesBehavior with the owner of the policy
Only a SOCKS proxy is availableClaude Code does not support SOCKS (v2.1.283)Request an HTTP proxy rule or route through an LLM gateway

For failures that are not network-related, start from Claude Code troubleshooting.

This page covers Claude Code only. Codex has read the system proxy configuration, including PAC and WPAD, since release 0.143.0 (per its GitHub release notes); see Codex configuration. Cursor’s network settings could not be verified against cursor.com on 2026-09-26, so check its own documentation before you write them into a rollout. The host allowlist above is specific to Claude Code: each tool needs its own vendor’s hosts.

Where to go next with Claude Code networking

Section titled “Where to go next with Claude Code networking”