Network configuration
Run Claude Code behind corporate proxies, TLS inspection and mTLS, tune streaming watchdogs, and know exactly which hosts to allowlist.
Corporate networks are where most "Claude Code won't connect" tickets come from. This page covers the knobs that matter: proxies, certificate trust, client certificates, the timers that detect dead streams, and the full list of hosts your firewall needs to let through.
Everything here is configured with environment variables, and all of them can live in the env block of a settings file instead of your shell. Shell exports are read once at startup; changing them later does not affect a running session.
Proxies
Claude Code honours the usual proxy variables:
export HTTPS_PROXY=http://proxy.corp.example:3128
export HTTP_PROXY=http://proxy.corp.example:3128 # only if there is no HTTPS proxy
export NO_PROXY="localhost,.corp.example,10.20.0.0/16" # comma or space separated; "*" bypasses everything
Lowercase names work too. Claude Code takes the first one set, in the order https_proxy, HTTPS_PROXY, http_proxy, HTTP_PROXY. WebSocket connections to localhost, ::1 and 127.0.0.0/8 never go via the proxy, so you do not need loopback entries in NO_PROXY.
A few limits:
- No SOCKS. Only HTTP and HTTPS proxies are supported.
- Basic auth goes in the URL, as in
http://svc-claude:secret@proxy.corp.example:3128. Keep the password out of scripts; load it from a secret store. - NTLM, Kerberos and friends are not supported directly. An LLM gateway that speaks your proxy's authentication scheme is the usual workaround.
In Claude Desktop sessions where the app manages the provider connection (see mTLS below for which those are), the proxy variables are read only from managed settings and ~/.claude/settings.json.
Certificate trust
By default Claude Code trusts two sets of roots: the Mozilla bundle it ships with, and your operating system's trust store. Reading the OS store needs a runtime with tls.getCACertificates, which the native installer always has; npm installs need Node 22.15 or later, otherwise only the bundled roots and NODE_EXTRA_CA_CERTS apply.
That means a TLS-inspecting proxy usually just works, as long as its root certificate is in the OS store. If you need more control:
| Variable | Effect |
|---|---|
CLAUDE_CODE_CERT_STORE=bundled | Trust only the shipped Mozilla roots |
CLAUDE_CODE_CERT_STORE=system | Trust only the OS store |
CLAUDE_CODE_CERT_STORE=bundled,system | The default |
NODE_EXTRA_CA_CERTS=/etc/pki/corp-root.pem | Add your own CA bundle on top |
CLAUDE_CODE_GZIP_REQUEST_BODIES=0 | Stop compressing request bodies, for inspection proxies that mangle gzip |
CLAUDE_CODE_CERT_STORE has no dedicated settings key; set it under env or in the process environment.
Client certificates (mTLS)
If your gateway or proxy demands a client certificate:
export CLAUDE_CODE_CLIENT_CERT=/etc/claude/tls/client.crt
export CLAUDE_CODE_CLIENT_KEY=/etc/claude/tls/client.key
export CLAUDE_CODE_CLIENT_KEY_PASSPHRASE="..." # only for an encrypted key
The files are read at startup and again whenever settings are applied (for example when an admin changes managed env mid-session).
Rotating certificates
Replace the files at the same paths; no restart is needed. From v2.1.232, when a request fails at the connection level (a reset or TLS handshake failure), Claude Code re-reads both files and retries with the new pair. Some details:
- Nothing happens the moment you swap the files. The new pair is used on the retry after a qualifying failure, or after the next settings application, whichever comes first.
- If the gateway completes the handshake and returns an HTTP error instead of rejecting the connection, there is no re-read; the new pair loads at the next settings application or restart.
- If Claude Code reads a half-written rotation (certificate and key that do not match), it keeps the previous pair and tries again next failure.
- OpenTelemetry exporters keep the certificate they loaded first, so restart for rotated certs to reach your collector.
CLAUDE_CODE_DISABLE_MTLS_RELOAD_ON_STALE_CONNECTION=1turns off the failure-triggered re-read.
To confirm a rotation, run with debug logging and search the log for the line that starts Stale connection and mentions reloaded rotated mTLS client material. A missing line is not proof of failure, because pickups during settings application are not logged. Always rotate before the old pair expires so a restart does not load an expired one.
Where these variables are ignored
In cloud sessions, the host manages the API connection, so these keys are ignored when they come from a settings file env block (each is noted in the debug log): CLAUDE_CODE_CLIENT_CERT, CLAUDE_CODE_CLIENT_KEY, CLAUDE_CODE_CLIENT_KEY_PASSPHRASE, NODE_EXTRA_CA_CERTS, NODE_TLS_REJECT_UNAUTHORIZED and CLAUDE_CODE_OAUTH_SCOPES.
In Claude Desktop sessions where the app owns the connection (the Code tab on a third-party provider, and Cowork), those variables and the proxy variables are read only from managed settings and ~/.claude/settings.json, never from a repository's own settings. That stops a cloned repo redirecting traffic for a session whose credentials come from the app. Local, SSH and WSL Code tab sessions signed in through claude.ai behave like the terminal and read every scope. (Before v2.1.217, these variables were ignored in every settings file whenever the app owned the connection.)
Checking your setup
Most of these values are not validated when read, so a typo usually surfaces as a connection or certificate error later. The exception is the proxy URL: if it cannot be parsed (missing http://, say), Claude Code refuses to start and names the variable.
To see what loaded before you send anything:
claude --debug-file /tmp/claude-net.log
(Plain --debug writes to ~/.claude/debug/<session-id>.txt.) Look for lines such as:
CA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (/etc/pki/corp-root.pem)
mTLS: Loaded client certificate from CLAUDE_CODE_CLIENT_CERT
mTLS: Loaded client key from CLAUDE_CODE_CLIENT_KEY
Failures show as Failed to read or Failed to load lines with a reason.
In /status:
- Proxy shows the active URL, or flags an unparseable one as invalid and ignored.
- mTLS client cert and mTLS client key appear only if the files loaded.
- Additional CA cert(s) shows the
NODE_EXTRA_CA_CERTSpath but does not prove the file loaded; check the debug log for that.
Background agents
Background agents run under a per-user supervisor process that starts on demand and outlives your terminal. It inherits the environment of whichever shell started it first, and an OS-installed supervisor gets no shell environment at all. So a proxy or CA path exported only in .zshrc reaches background agents some of the time, which is the worst kind of bug.
Put network variables in ~/.claude/settings.json or managed settings. Settings are the only thing that reliably reaches every background session.
The same applies to corporate launchers. The supervisor starts Claude Code from a fixed path, not via PATH, so a wrapper earlier on PATH is bypassed. Use the processWrapper setting (or CLAUDE_CODE_PROCESS_WRAPPER, which wins if both are set, delivered through settings, not the shell). See corporate launcher. After changing it, run claude daemon stop --any so the next background session starts a supervisor with the new configuration (an installed service takes claude daemon stop without --any).
Streaming watchdogs
Four independent timers abort a model response that goes quiet, so a dead connection fails and retries rather than hanging forever:
| Timer | Fires when | Applies to | Default |
|---|---|---|---|
| First-byte deadline | No response headers after sending | Direct Anthropic API and Claude Platform on AWS (including via an HTTPS proxy), but not when a gateway base URL is set. Opt-in on Bedrock; never on Vertex AI or Foundry. | 180 s on the direct API, 300 s elsewhere, plus 1 s per 32 KB of request body |
| Event-level watchdog | No response events parse | All providers. Where the byte watchdog runs (except Bedrock), incoming bytes also reset it, for up to about five minutes without an event. | 300 s |
| Byte-level watchdog | No bytes at all, keep-alives included | Direct API, Claude Platform on AWS and gateway connections including a custom ANTHROPIC_BASE_URL. Opt-in on Bedrock; never on Vertex AI or Foundry. | 180 s on the direct API; through a custom base URL, 180 s with feature flags fetched, 300 s without; 300 s elsewhere |
| Body idle timeout | No bytes for five minutes | Providers other than the direct API, Claude Platform on AWS and opted-in Bedrock, unless API_FORCE_IDLE_TIMEOUT says otherwise | 5 min |
CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1 turns on the byte watchdog for Bedrock's event-stream responses, replacing the body idle timeout there. CLAUDE_STREAM_IDLE_TIMEOUT_MS then also governs Bedrock silence. Bytes still do not reset the event watchdog on Bedrock, and with debug logging each stream logs a line beginning wire-heartbeat: _chunkTimes absent.
Tuning variables (full details in environment variables):
| Variable | What it does |
|---|---|
CLAUDE_ENABLE_STREAM_WATCHDOG | 1/0 forces the event watchdog on or off where it applies |
CLAUDE_ENABLE_BYTE_WATCHDOG | 1/0 forces the byte watchdog on or off where it applies; 0 also disables the first-byte deadline |
CLAUDE_STREAM_IDLE_TIMEOUT_MS | Timeout for both watchdogs. Raised to at least 5 minutes; capped at 30 minutes for the byte watchdog |
CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS | Byte watchdog only, clamped to 10 s to 30 min; beats the previous variable |
CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS | First-byte deadline directly; unset, it follows the byte watchdog timeout |
API_FORCE_IDLE_TIMEOUT | 0 disables the body idle timeout, 1 enables it everywhere. Watchdogs run regardless, so raise them too if streams legitimately pause |
When a watchdog fires mid-stream, Claude Code may retry, end the turn with an error, keep what arrived and show an incomplete-response notice, or end normally, depending on how far the response got. In headless sessions and subagents it may first ask Claude to continue the cut-off response. A first-byte abort has no partial output, so it simply re-sends or fails. The errors page covers each case.
Hosts to allowlist
For the standalone CLI:
| Host | Used for |
|---|---|
api.anthropic.com | Model requests, the WebFetch domain safety check, feature flags, telemetry event logging |
claude.ai | claude.ai account authentication |
claude.com | The browser sign-in page (redirects to claude.ai); some pre-approved documentation fetches |
platform.claude.com | Console authentication, and OAuth token exchange, refresh and revocation for claude.ai accounts too |
mcp-proxy.anthropic.com | claude.ai MCP connectors. Disable with ENABLE_CLAUDEAI_MCP_SERVERS=false or disableClaudeAiConnectors |
downloads.claude.ai | Plugin executables, native installer, auto-updater and version checks |
storage.googleapis.com | Plugin install counts and metadata in /plugin; the installer and updater before v2.1.116 |
registry.npmjs.org | npm-source plugins and their dependencies, npx MCP servers, and npm or bun installs of Claude Code |
bridge.claudeusercontent.com | The Claude in Chrome WebSocket bridge |
*.frame.claudeusercontent.com | Reading artifact content. Drop with "enableArtifact": false or CLAUDE_CODE_DISABLE_ARTIFACT=1 |
github.com | Cloning plugin marketplaces and plugins, including Anthropic's. CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1 forces HTTPS for owner/repo sources |
raw.githubusercontent.com | The /release-notes changelog (also fetched in the background on the first interactive start after an update) |
*-review.googlesource.com | Gerrit change lookup for trusted googlesource.com checkouts in Desktop Code tab sessions; optional |
http-intake.logs.us5.datadoghq.com | Operational telemetry, direct Anthropic API only; optional |
browser-intake-us5-datadoghq.com | Operational error reports, direct API only, when enabled server-side; optional |
formulae.brew.sh | Update checks on Homebrew installs only |
code.claude.com | Documentation lookups by the built-in guide agent and pre-approved WebFetch; blocking it only affects those |
Notes for building the allowlist:
- If you install via npm or distribute the binary yourself, you do not need the installer and updater uses of
downloads.claude.ai, but npm and bun installs needregistry.npmjs.orgunless you mirror it. CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICturns off both Datadog hosts. Third-party provider sessions never send to them.- On Bedrock, Vertex AI, Foundry or a signed-in Claude apps gateway, model and auth traffic goes to your provider instead. WebFetch still calls
api.anthropic.comfor its safety check unless you setskipWebFetchPreflight: true. - Behind an
ANTHROPIC_BASE_URLgateway, the fast mode availability check still callsapi.anthropic.com(honouring your HTTP proxy). A blocked host and a gateway credential Anthropic rejects both show as a connectivity error; only the first is fixed by allowlisting.
IP allowlisting for Claude
If your organisation uses IP allowlisting for Claude, send bridge.claudeusercontent.com out through the same proxy egress as claude.ai and api.anthropic.com (same Zscaler app segment or Netskope steering policy, for example). Connections to it are checked against your allowlist by source address, so if it egresses elsewhere the Chrome extension fails while everything else works. Only add a proxy's egress address to your allowlist if that address is dedicated to you; a shared range admits the vendor's other customers.
GitHub IP restrictions
Cloud sessions in Anthropic-hosted environments and Code Review reach your repositories from Anthropic infrastructure. Self-hosted environment sessions connect from inside your network unless their runner uses the Anthropic git proxy.
For GitHub Enterprise Cloud with IP restrictions, enable IP allow list inheritance for installed GitHub Apps and add Anthropic's published outbound IP addresses; inheritance only covers requests the app makes as an installation, not on behalf of users. For GitHub Enterprise Server behind a firewall, allowlist the same outbound addresses so hosted sessions, the repository picker and git-proxy runners can reach it.
Desktop and the browser
The table above is for the CLI. Claude Desktop and claude.ai also load code and content from additional CDN hosts such as assets-proxy.anthropic.com and other *.claudeusercontent.com origins; blocking them gives a blank page rather than an error. Interactive widgets such as MCP Apps load from *.claudemcpcontent.com (keep the wildcard).
Artifacts may request fonts.googleapis.com and fonts.gstatic.com (optional; fallback fonts are used) and JavaScript libraries from cdnjs.cloudflare.com, cdn.jsdelivr.net, cdn.tailwindcss.com, code.jquery.com and unpkg.com (no fallback). If you block any of these, reject quickly rather than silently dropping, so pages do not hang waiting.