What you will learn
- Claude Code does not pin TLS certificates, so it runs through full inspection once it trusts your CA. Do not exempt it from the proxy.
- As of mid-2026 the CLI trusts your OS certificate store by default via
CLAUDE_CODE_CERT_STORE. The months of cert failures came from the Bun runtime, now mostly fixed. - The
/statusscreen will tell you the certificate is set when it is not. Trust the request, not the status line. - The CLI, the IDE extension, the Desktop Code pane, and Cowork each fail in their own way. Test all four before you call it done.
- Never silence the error by turning certificate validation off. That trades a warning for a wide-open API key.
The first time a corporate proxy ate my Claude Code, I lost an afternoon to four words: unable to get local issuer certificate. My own laptop, my own setup. A full-tunnel VPN had switched on TLS inspection, which quietly terminates every HTTPS connection, reads it, then re-signs it with the VPN’s own root certificate before passing it along. My browser trusted that certificate. Claude Code didn’t. So every call to api.anthropic.com failed, the error handed me four rubbish words and nothing else, and the tool sat there useless until I dropped the VPN.
The whole thing fits in one breath. The proxy was never the problem. Claude Code doesn’t pin TLS certificates, so it runs fine through full break-and-inspect once you teach the tool to trust your corporate root CA. The fix is a couple of environment variables and an egress allowlist. It isn’t a proxy exception, and reaching for one is the wrong instinct in a locked-down shop.
That afternoon I burned was yak shaving of the purest kind. I was fighting the network.
The tool had been willing all along.
Stop trying to make the proxy do the work
In a regulated shop the reflex is to treat Claude Code as the awkward exception: exempt it from inspection, punch a hole in egress, get the network team to wave api.anthropic.com straight past the break-and-inspect engine so the error disappears. I get the reflex. It’s wrong twice over. You’ve just blinded your own data-loss and threat inspection for one application, which is the opposite of what a regulated environment is paying for. And it often doesn’t even clear the error, because the failure sits on the tool’s side. Claude can’t find your corporate root CA in a trust store it actually reads, so it rejects the re-signed connection. The proxy did its job. The tool refused the result.
So should you just exempt Claude from inspection and be done? No. You’d blind your own monitoring for one app, and nine times in ten the cert error is still sitting there afterwards.
That distinction is the game. The people behind a MITM-proxy walkthrough for these CLIs say it without flinching: neither Claude Code nor Codex CLI pins certificates today. No pinning means a corporate man-in-the-middle proxy is meant to work.
You’re allowed to terminate, inspect, and re-sign Claude Code’s traffic, the same way you already do for Chrome. When it breaks, it breaks because the tool couldn’t locate your root CA in a store it reads, not because it caught your inspection and slammed the door.
Security teams get this backwards constantly. They assume the tool is rejecting the proxy on purpose, some clever anti-tamper thing. It’s not that clever. It just couldn’t load the certificate. Reframe the whole investigation around that, and you stop hunting for a setting to disable and start hunting for the trust store to populate.
Four variables and one allowlist
Almost everything you need sits in Anthropic’s network-config page, and the good news is the defaults moved in your favour. Claude Code now trusts both its bundled Mozilla CA set and your operating system’s certificate store out of the box. In most shops the cert error never even shows up, because your corporate root CA is already sitting in the OS trust store your endpoint team pushed months ago. The control is CLAUDE_CODE_CERT_STORE, default bundled,system. Drop it to system to ignore Mozilla’s set, or bundled to ignore the OS store.
Leave it alone and the OS store does the work.
Here’s the rest of the surface, kept to what earns its place:
| Variable | What it does | When to set it |
|---|---|---|
CLAUDE_CODE_CERT_STORE | Picks the trust stores: bundled, system, or both | Leave at bundled,system. Your corporate CA in the OS store covers most cases |
NODE_EXTRA_CA_CERTS | Path to a single PEM of extra CAs to trust | When your CA is not in the OS store, or you want an explicit file. Set it as a real shell variable |
CLAUDE_CODE_CLIENT_CERT / _KEY | Client certificate and key for mutual TLS | Only if your proxy demands the client prove itself too. _KEY_PASSPHRASE for an encrypted key |
HTTPS_PROXY / NO_PROXY | Standard proxy routing and bypass list | Point at your proxy. List internal hosts in NO_PROXY, space or comma separated. No SOCKS support |
For the common case, two lines in your shell profile do it:
export CLAUDE_CODE_CERT_STORE=bundled,system
export NODE_EXTRA_CA_CERTS=/etc/pki/corp-root-ca.pemThen the allowlist. If your firewall is default-deny, Claude needs api.anthropic.com for the API, claude.ai and platform.claude.com for sign-in, downloads.claude.ai for the installer and updates, and raw.githubusercontent.com for the changelog feed. One currency note worth catching: storage.googleapis.com only matters on versions before 2.1.116, after which the installer moved to downloads.claude.ai. The page doesn’t list statsig.anthropic.com or Sentry in that table, because those are optional telemetry. Allowlist api.anthropic.com alone and you’ll still get event-logging errors nagging in the corner until you disable telemetry, so settle that before you finalise the firewall rules.
One trap to call out loudly, because half the answers online walk straight into it. The error vanishes if you set NODE_TLS_REJECT_UNAUTHORIZED=0. Do not. That doesn’t add trust, it removes verification, so anything on the wire can read your API key in plaintext.
Add the CA. Never switch the check off.
I went back and forth on whether to even name that flag here, but it’s too common to skip, and it’s the single most dangerous bit of advice floating around on this topic.
A quick rewind on why the defaults are recent, because the history explains the bug you might still hit. Claude Code switched from a Node.js-launched CLI to a binary compiled with the Bun runtime in early 2026, and Bun ships its own TLS stack. For months that stack didn’t honour the OS trust store, and one closed-as-not-planned bug report traced it precisely: the binary runs in Bun, the WebFetch tool’s bundled undici client builds its own dispatcher, and that dispatcher never reads the patched CA store. Which is exactly as fun to debug as it sounds. The community fix was NODE_USE_SYSTEM_CA=1, a Node runtime flag that forces the OS store to load. Anthropic has since shipped a first-class setting that does the same job, which is CLAUDE_CODE_CERT_STORE. On an older build where the OS store is being ignored, that env var is your bridge until you update.
One correction to myself, because I keep calling this a tool problem and that undersells a bit of it. Your proxy still has to actually present the corporate CA on every connection, and a handful of inspection products do that unevenly from one application to the next. So confirm the proxy is really in the path before you blame the binary.
Why does /status say the cert is set?
Because the status screen and the live network request read different things, and that gap is the villain of this whole topic. Picture it. You put NODE_EXTRA_CA_CERTS in your ~/.claude/settings.json, you run /status, it confirms the extra CA is loaded, and you relax. Then every request still fails with a self-signed-certificate error. A closed bug report documents exactly this: the settings-file CA variables aren’t honoured when requests go out, even though /status reports them as set, and only the real shell environment, exported before you launch claude, takes effect. The diagnostic lies. A tool that swears it’s configured when it isn’t is worse than one that stays quiet, because it sends you looking everywhere except the real cause. Set the CA in your shell, not in settings.json, and check it by making an actual request rather than reading a status line.
Silent failure is the pattern to watch for, not just this one instance of it. A few more wear the same disguise. You test “can it reach the API,” it passes, you ship, and then WebFetch breaks a day later because its network stack reads CA trust differently from the main client. You set NO_PROXY for your internal hosts and some versions ignore it, force-proxying traffic that should have gone direct, with no warning they did. And the nastiest one across an estate of hundreds of machines: a routine auto-update bumps the bundled runtime, and a laptop that worked yesterday throws cert errors today for no reason the user can see. None of these announce themselves. Every one costs a support ticket and an afternoon, the same afternoon I burned, multiplied across the whole rollout. It’s a bit of a nightmare precisely because nothing is technically broken.
So the rule I give teams is blunt. Don’t trust any green checkmark in this tool’s own self-report. Trust a real request completing.
Build that into your pilot test, not your post-mortem.
The same tool fails four different ways
This is the bit people miss, and it’s the reason “we tested it, it works” isn’t the same as “it’s ready.” Claude Code is four different network stacks wearing one name, and a fix on one doesn’t carry to the others. Test all four straightaway, because a CIO who proves the CLI works and then rolls out to the IDE crowd will be back inside a week.
| Surface | Why it breaks | What works |
|---|---|---|
| CLI | Bun-compiled binary; older builds ignored the OS store | Most fixable. Shell-set CLAUDE_CODE_CERT_STORE / NODE_EXTRA_CA_CERTS; the default OS trust now covers most cases |
| VS Code / JetBrains extension | Spawns the same binary in an isolated trust context; your OS CA does not reach it | Set the CA variables in the environment the IDE itself launches from, not just your interactive shell |
| Claude Desktop, Code pane | The code subprocess does not inherit the parent app’s CA settings; chat works, the Code pane fails | Set the CA at the OS or system level so the child process sees it |
| Cowork (Linux VM) | The VM has no view of the host proxy; egress is allowlisted server-side in a signed token, so editing local config does nothing | Least fixable today. Treat it as a separate egress problem, via a host-proxy-aware relay or a gateway |
Two surfaces deserve a footnote. The Cowork VM is its own animal: changing a config file on disk does nothing, because the egress allowlist lives in a server-side token rather than on your machine, which is a different kind of problem from a missing CA. Then there’s authenticated proxies. If yours speaks NTLM or Kerberos rather than basic auth, no environment variable saves you, because the tool’s HTTP client can’t do Windows Integrated Authentication. Anthropic’s own docs punt to an LLM gateway here, and a corporate-proxy walkthrough by Hidekazu Konishi lands in the same place: run a local relay like cntlm to answer the NTLM challenge, or front the whole thing with a gateway. Turns out if you’re standing up a gateway anyway, it pays a second dividend on the inspection and logging side, which is the case I made for AI gateways separately.
Write the runbook for the day it flips
Here’s the advice I haven’t seen in a single vendor note, and the one I’d lead with for any CISO. Today you can fully inspect Claude Code, because it doesn’t pin certificates. Write that sentence in your runbook with today’s date beside it, because it’s a fact with a shelf life. The same MITM-proxy people who confirmed no pinning today also flagged the catch: a future update could add it, and the warning sign will be Claude suddenly refusing a proxied handshake that worked the day before. The day that lands, your fix inverts. “Add our CA so the tool trusts the proxy” becomes “carve the tool out of inspection outright,” because a pinned client won’t accept your re-signed certificate at any price. That’s a different change request, a different approval, a different owner. Decide now who watches for the flip and what they do when it comes, so it’s a planned switch and not a proper Monday-morning outage.
Mind you, none of this is the hard part of running an agentic tool in a regulated company. Getting it to connect is the easy ten percent. The other ninety, the audit trail, the permission policy, prompt injection, the blast radius of a tool that runs shell commands on your behalf, is a design problem, and I wrote the security side of it as its own piece. This post is the connectivity floor that one stands on, one of the four jobs that make up phase zero. Lay it properly and you never think about it again.
So the order is small and boring, which is how you know it’s right. Trust your CA, leave CLAUDE_CODE_CERT_STORE on its default, set NODE_EXTRA_CA_CERTS only if your CA lives outside the OS store, allowlist the handful of domains, and test the surface your people actually use. Then forget the proxy and go do the real work.
The tool was on your side the whole time. It just needed to recognise your certificate, the way your browser already does.





