Solo Stack Kits Directory
Claude Code workflows & skills for solo consultants and freelancers

← 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 host or 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 run claude --debug and /status before 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

  1. 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) or Unable to connect to API: Self-signed certificate detected (SELF_SIGNED_CERT_IN_CHAIN), followed by a hint to set NODE_EXTRA_CA_CERTS. During /login or the startup check you'll see SSL 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 set NODE_TLS_REJECT_UNAUTHORIZED=0: it turns off certificate checking entirely. Before v2.1.273 both messages just ended with Check 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).
  2. 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 and NODE_EXTRA_CA_CERTS count, 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 setting NODE_EXTRA_CA_CERTS. Also check that CLAUDE_CODE_CERT_STORE isn't set to bundled, which ignores the OS store.
  3. NODE_EXTRA_CA_CERTS is set but never loaded. Three usual reasons: you exported it after starting claude (restart the session), the path is wrong, or the file isn't a PEM certificate file, which is the format Node expects. /status shows the Additional CA cert(s) path without checking that the file loaded, so don't trust it alone. Start with claude --debug and open the log in ~/.claude/debug/<session-id>.txt (or the path you pass with --debug-file): a working setup logs CA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (...), and a broken one logs a Failed to read or Failed to load line with the reason.
  4. The installer fails before Claude Code exists. The install script is downloaded by curl or PowerShell, not by Claude Code, so NODE_EXTRA_CA_CERTS doesn't help yet. Errors like curl: (35) TLS connect error, unable to get local issuer certificate, SELF_SIGNED_CERT_IN_CHAIN or PowerShell's Could not establish trust relationship for the SSL/TLS secure channel mean 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-certificates on Ubuntu/Debian), and in Windows PowerShell 5.1 enable TLS 1.2 first with [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12. Once installed, set NODE_EXTRA_CA_CERTS for Claude Code itself (cause 1). More install failures are in our command not found guide.
  5. Windows blocks the certificate revocation check. CRYPT_E_NO_REVOCATION_CHECK (0x80092012) or CRYPT_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 with curl --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 with winget install Anthropic.ClaudeCode. Best-effort checking still rejects a certificate known to be revoked.

Proxy settings: 5 causes

  1. 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, or Unable to connect to Anthropic services on 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 order https_proxy, HTTPS_PROXY, http_proxy, HTTP_PROXY, so a stale lowercase value in your profile beats the uppercase one you just exported. Run /status and check the Proxy row for the URL it actually uses.
  2. 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 /status marks it invalid and ignored. Claude Code doesn't support SOCKS proxies at all, so a socks5:// address won't work; use an HTTP(S) proxy.
  3. 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 host means 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. A 407 from the proxy means it wanted credentials, 403 means 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 with curl -x http://proxy.example.com:8080 -I https://api.anthropic.com.
  4. NO_PROXY sends the wrong traffic around the proxy. NO_PROXY takes a space- or comma-separated list such as localhost,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 proxies localhost, ::1 or 127.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.com in NO_PROXY, not all of .claudeusercontent.com.
  5. 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 received means 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 request usually 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 closed most often comes from a corporate proxy on Windows dropping a tunnel mid-response; v2.1.214 and later retry it, so run claude update. And if the proxy holds responses until they finish, raise API_TIMEOUT_MS so Claude Code waits longer.

Firewall, VPN and mTLS: 3 causes

  1. The firewall blocks a host Claude Code needs. The core list for the CLI: api.anthropic.com (API requests), claude.ai and claude.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.com if your organization uses SSO, and downloads.claude.ai for the native installer and updates. npm installs need registry.npmjs.org, which also serves plugin installs and npx-launched MCP servers; mcp-proxy.anthropic.com carries claude.ai MCP connectors, and github.com is 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, set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1.
  2. A VPN, DNS resolver or leftover setting sends traffic nowhere. Can't reach the API server — check your internet or DNS (ENOTFOUND) and No internet route — check your connection or VPN (EHOSTUNREACH) point at the network path. A VPN can block api.anthropic.com outright. If curl works but Claude Code still fails: run echo $ANTHROPIC_BASE_URL (a leftover value pointing at a proxy or gateway that's no longer running gives Connection refused); on Linux and WSL check /etc/resolv.conf for an unreachable nameserver; on macOS look in ifconfig for stale utun interfaces from a disconnected or uninstalled VPN; and quit Docker Desktop or similar runtimes, which can intercept outbound traffic, to rule them out.
  3. mTLS: the client certificate isn't loaded. If your gateway requires client certificates, set CLAUDE_CODE_CLIENT_CERT and CLAUDE_CODE_CLIENT_KEY to the PEM files, plus CLAUDE_CODE_CLIENT_KEY_PASSPHRASE for 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 a Failed to read or Failed to load reason. 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

  1. Background agents don't see your shell exports. Sessions started with claude agents, --bg or /background run 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 the env block 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 run claude 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_STORE has no settings key of its own, so set it in that env block too. If other env values seem ignored, our settings not applying guide shows which file wins.
  2. 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 ignore NODE_EXTRA_CA_CERTS, NODE_TLS_REJECT_UNAUTHORIZED and the client certificate variables from any settings env block, 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.

Want it set up already? Claude Code Power Config Pack

Fixed it? Skip the next one with a tested Claude Code setup you can drop into any repo.

One install command that backs up your settings first. Checked against the official Claude Code docs. MIT licensed.

Launch price: $6 instead of $12 (code LAUNCH50, first 25 buyers, until Nov 10, 2026).

Get the Config Pack: $6 launch priceOr try 2 of the hooks free

Free on Gumroad: block-dangerous-bash and protect-secrets with a settings snippet. Enter $0; Gumroad asks for an email to deliver the zip.

Prefer to build it yourself? Use the free Claude Code tools, no sign-up.