← Blog · 2026-11-01
Claude Code Behind a Corporate Proxy? SSL Certificate Errors: 15 Causes and Fixes
60-second test: from the same shell you start Claude Code in, run
curl -I https://api.anthropic.com(on Windows PowerShell,curl.exe -I ...). A certificate error from curl too means something on your network is re-signing TLS traffic: start with causes 1 to 3. No answer,Could not resolve hostor a timeout is a proxy, firewall or VPN problem (causes 6 to 12). curl works but Claude Code doesn't usually means Claude Code isn't seeing your settings (causes 3, 6 and 14), so runclaude --debugand/statusbefore changing anything else.
Claude Code makes its own HTTPS connections, so it needs to know two things your browser may already handle for you: which proxy to use and which certificate authorities to trust. All of it comes from environment variables you set before you launch claude. Variables exported in your shell are read once at startup, so a running session doesn't see later changes.
| Setting | What it does | Default |
|---|---|---|
HTTPS_PROXY / HTTP_PROXY |
Sends traffic through your proxy | None |
NO_PROXY |
Hosts that skip the proxy | None |
CLAUDE_CODE_CERT_STORE |
Which CA sets to trust: bundled (Mozilla set shipped with Claude Code), system (your OS store) |
bundled,system |
NODE_EXTRA_CA_CERTS |
Adds your organization's CA bundle | None |
CLAUDE_CODE_CLIENT_CERT / CLAUDE_CODE_CLIENT_KEY |
Client certificate for mTLS | None |
Every one of these can also go in the env block of a settings file. Claude Code doesn't validate most of them when it reads them, so a wrong path or address usually shows up later as a connection or certificate error. The fifteen causes below cover almost every "works everywhere except at work" report.
Certificate errors: 5 causes
- A TLS-inspecting proxy re-signs traffic with a CA Claude Code doesn't trust. This is the classic corporate network error. Current versions print
Unable to connect to API: SSL certificate verification failed (UNABLE_TO_GET_ISSUER_CERT_LOCALLY)orUnable to connect to API: Self-signed certificate detected (SELF_SIGNED_CERT_IN_CHAIN), followed by a hint to setNODE_EXTRA_CA_CERTS. During/loginor the startup check you'll seeSSL certificate error (UNABLE_TO_GET_ISSUER_CERT_LOCALLY)instead. Get your organization's CA bundle from IT and point Claude Code at it:export NODE_EXTRA_CA_CERTS=/path/to/ca-bundle.pem(PowerShell:$env:NODE_EXTRA_CA_CERTS = 'C:\path\to\corporate-ca.pem'), then start a new session. Do not setNODE_TLS_REJECT_UNAUTHORIZED=0: it turns off certificate checking entirely. Before v2.1.273 both messages just ended withCheck your proxy or corporate SSL certificates, and before v2.1.199 Claude Code retried certificate failures for a few minutes before showing them, which looks like a hang (see Claude Code stuck or not responding). - The CA is in your OS trust store, but Claude Code can't read the store. By default Claude Code trusts both its bundled Mozilla CAs and your operating system's store, so a proxy whose root certificate IT installed on your machine normally works with no setup. Reading the OS store needs a runtime with
tls.getCACertificates: the native installer always has it, but an npm install needs Node 22.15 or later. On older Node, only the bundled set andNODE_EXTRA_CA_CERTScount, so the same laptop can work with the native build and fail with npm. Fix it by switching to the native installer, upgrading Node, or settingNODE_EXTRA_CA_CERTS. Also check thatCLAUDE_CODE_CERT_STOREisn't set tobundled, which ignores the OS store. NODE_EXTRA_CA_CERTSis set but never loaded. Three usual reasons: you exported it after startingclaude(restart the session), the path is wrong, or the file isn't a PEM certificate file, which is the format Node expects./statusshows the Additional CA cert(s) path without checking that the file loaded, so don't trust it alone. Start withclaude --debugand open the log in~/.claude/debug/<session-id>.txt(or the path you pass with--debug-file): a working setup logsCA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (...), and a broken one logs aFailed to readorFailed to loadline with the reason.- The installer fails before Claude Code exists. The install script is downloaded by
curlor PowerShell, not by Claude Code, soNODE_EXTRA_CA_CERTSdoesn't help yet. Errors likecurl: (35) TLS connect error,unable to get local issuer certificate,SELF_SIGNED_CERT_IN_CHAINor PowerShell'sCould not establish trust relationship for the SSL/TLS secure channelmean the TLS handshake failed. On macOS and Linux, give curl your corporate CA:curl --cacert /path/to/corporate-ca.pem -fsSL https://claude.ai/install.sh | bash. On Windows, the PowerShell installer validates against the Windows certificate store, so IT needs to add the proxy's CA there. Also update your system CA certificates (sudo apt-get update && sudo apt-get install ca-certificateson Ubuntu/Debian), and in Windows PowerShell 5.1 enable TLS 1.2 first with[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12. Once installed, setNODE_EXTRA_CA_CERTSfor Claude Code itself (cause 1). More install failures are in our command not found guide. - Windows blocks the certificate revocation check.
CRYPT_E_NO_REVOCATION_CHECK (0x80092012)orCRYPT_E_REVOCATION_OFFLINE (0x80092013)means curl reached the server but your network blocks the revocation lookup, which is common behind corporate firewalls. Rerun the CMD install withcurl --ssl-revoke-best-effort -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd, use the PowerShell installer (irm https://claude.ai/install.ps1 | iex), or skip curl withwinget install Anthropic.ClaudeCode. Best-effort checking still rejects a certificate known to be revoked.
Proxy settings: 5 causes
- The proxy isn't set where Claude Code can see it. If your network needs a proxy and Claude Code doesn't know, you'll get
Unable to connect to API,Request timed out. Check your internet connection and proxy settings, orUnable to connect to Anthropic serviceson first run. Set it before launching:export HTTPS_PROXY=http://proxy.example.com:8080(ask IT for the address, or copy it from your browser's proxy settings). Lowercase names work too; Claude Code uses the first one set in the orderhttps_proxy,HTTPS_PROXY,http_proxy,HTTP_PROXY, so a stale lowercase value in your profile beats the uppercase one you just exported. Run/statusand check the Proxy row for the URL it actually uses. - The proxy URL can't be parsed, or it's the wrong kind of proxy. Claude Code checks the proxy URL at startup: a value it can't parse, such as one missing the
http://scheme, stops launch with an error naming the variable to fix, and/statusmarks it invalid and ignored. Claude Code doesn't support SOCKS proxies at all, so asocks5://address won't work; use an HTTP(S) proxy. - The proxy wants credentials it isn't getting.
Couldn't connect through your proxy (ERR_PROXY_TUNNEL) — the proxy refused the tunnel: check its credentials and that it allows this hostmeans the proxy rejected the connection. For basic authentication, put the credentials in the URL:export HTTPS_PROXY=http://username:password@proxy.example.com:8080, but keep the password out of scripts you commit. A407from the proxy means it wanted credentials,403means it refuses that host. Claude Code has no built-in NTLM or Kerberos proxy authentication; Anthropic suggests putting an LLM gateway that supports your method in between. Test the proxy itself withcurl -x http://proxy.example.com:8080 -I https://api.anthropic.com. NO_PROXYsends the wrong traffic around the proxy.NO_PROXYtakes a space- or comma-separated list such aslocalhost,192.168.1.1,example.com,.example.com, and*bypasses the proxy for everything. If a host listed there can only be reached through the proxy, those requests fail. You don't need loopback entries for Claude Code's own WebSocket connections: it never proxieslocalhost,::1or127.0.0.0/8. If Claude can't open artifacts through the proxy (proxy refused the connection: HTTP 403), the narrow fix is.frame.claudeusercontent.cominNO_PROXY, not all of.claudeusercontent.com.- The proxy gets through but mangles the traffic. A few failures only happen behind proxies. If a TLS-inspecting proxy mishandles compressed request bodies, set
CLAUDE_CODE_GZIP_REQUEST_BODIES=0.Streaming response ended before any complete data was receivedmeans a proxy or gateway is consuming or rewriting the streaming response, so ask for it to be passed through unmodified.API returned an empty or malformed response (HTTP 200) — check for a proxy or gateway intercepting the requestusually means an HTML page, such as a guest Wi-Fi sign-in page, answered instead of the API; sign in through a browser and retry.Socket is closedmost often comes from a corporate proxy on Windows dropping a tunnel mid-response; v2.1.214 and later retry it, so runclaude update. And if the proxy holds responses until they finish, raiseAPI_TIMEOUT_MSso Claude Code waits longer.
Firewall, VPN and mTLS: 3 causes
- The firewall blocks a host Claude Code needs. The core list for the CLI:
api.anthropic.com(API requests),claude.aiandclaude.com(claude.ai sign-in),platform.claude.com(Console sign-in, and token exchange and refresh for claude.ai accounts too, so every sign-in needs it),sso.claude.comif your organization uses SSO, anddownloads.claude.aifor the native installer and updates. npm installs needregistry.npmjs.org, which also serves plugin installs andnpx-launched MCP servers;mcp-proxy.anthropic.comcarries claude.ai MCP connectors, andgithub.comis needed to clone GitHub-hosted plugin marketplaces. If only sign-in breaks, see our login not working guide; if only updates break, see Claude Code not updating. To cut optional traffic (auto-updates, telemetry, error reporting) before you finalize an allowlist, setCLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1. - A VPN, DNS resolver or leftover setting sends traffic nowhere.
Can't reach the API server — check your internet or DNS (ENOTFOUND)andNo internet route — check your connection or VPN (EHOSTUNREACH)point at the network path. A VPN can blockapi.anthropic.comoutright. Ifcurlworks but Claude Code still fails: runecho $ANTHROPIC_BASE_URL(a leftover value pointing at a proxy or gateway that's no longer running givesConnection refused); on Linux and WSL check/etc/resolv.conffor an unreachable nameserver; on macOS look inifconfigfor staleutuninterfaces from a disconnected or uninstalled VPN; and quit Docker Desktop or similar runtimes, which can intercept outbound traffic, to rule them out. - mTLS: the client certificate isn't loaded. If your gateway requires client certificates, set
CLAUDE_CODE_CLIENT_CERTandCLAUDE_CODE_CLIENT_KEYto the PEM files, plusCLAUDE_CODE_CLIENT_KEY_PASSPHRASEfor an encrypted key. In/status, the mTLS client cert and mTLS client key rows appear only when the files loaded; a missing row means the debug log has aFailed to readorFailed to loadreason. To rotate, replace the files at the same paths: from v2.1.232, a connection reset or TLS handshake failure makes Claude Code re-read both files and retry without a restart.
Where you set the variables: 2 causes
- Background agents don't see your shell exports. Sessions started with
claude agents,--bgor/backgroundrun in a shared supervisor process that inherits the environment of whichever shell started it first. A proxy, CA or mTLS variable exported only in your shell reaches them sometimes and silently not at other times. Put the same variables in theenvblock of~/.claude/settings.json(or managed settings), for example{"env": {"HTTPS_PROXY": "http://proxy.example.com:8080", "NODE_EXTRA_CA_CERTS": "/path/to/ca-bundle.pem"}}, then runclaude daemon stop --any: a supervisor that's already running keeps the configuration it started with, so stopping it lets the next background session start fresh.CLAUDE_CODE_CERT_STOREhas no settings key of its own, so set it in thatenvblock too. If otherenvvalues seem ignored, our settings not applying guide shows which file wins. - The session type ignores the settings file you used. In Claude Desktop sessions where the app manages the provider connection, such as the Code tab on a third-party provider and Cowork, Claude Code reads the proxy, CA and mTLS variables only from managed settings and
~/.claude/settings.json, never from a repository's settings files. Cloud sessions go further and ignoreNODE_EXTRA_CA_CERTS,NODE_TLS_REJECT_UNAUTHORIZEDand the client certificate variables from any settingsenvblock, because the hosting environment manages the connection. Claude Code notes each ignored key in the debug log.
Installed with npm, or using Amazon Bedrock?
npm downloads packages with its own network settings, so a proxy that blocks npm install -g @anthropic-ai/claude-code is fixed in npm's config rather than Claude Code's: check npm config get https-proxy and point npm at your CA with npm config set cafile /path/to/corporate-ca.pem. The native installer avoids npm entirely. On Amazon Bedrock, Claude Code applies the same CA configuration (OS store or NODE_EXTRA_CA_CERTS) to its requests to AWS, including the STS and SSO credential calls; before v2.1.260 it did so only when those requests went through a proxy. For HTTP errors that aren't about the network, such as 429s, 500s or overloaded, see Claude Code API error.
Facts on this page come from Anthropic's Claude Code docs on enterprise network configuration, errors, troubleshooting installation and login, environment variables, the settings reference and Amazon Bedrock, plus standard Node.js and npm behavior. This guide isn't affiliated with Anthropic.
Made by Solo Stack Kits. Once Claude Code gets through your network, keep it on a short leash. Start with our free Claude Code safety hooks, or get the Claude Code Power Config Pack with permission presets and 8 tested safety hooks, $6 with the launch code while it lasts.