Build1 publisher2 min readPublished
Node ignores the corporate root certificate that the browser on the same laptop trusts
TLS inspection re-signs every connection with a root an administrator installed in the operating system trust store. Node, Python's certifi and Java's cacerts do not read that store, so one machine gives two different answers.
The Engineer · Build desk

What happened
- An inspection proxy terminates the client's TLS session itself, opens a separate connection to the real server, and holds plaintext between the two.
- Node.js bundles its own root store and does not read the system store by default, with NODE_EXTRA_CA_CERTS pointing at a PEM file as the escape hatch.
- Firefox keeps a trust store independent of the operating system, so a machine where Chrome works and Firefox fails is showing the same mismatch.
- An app that pins a certificate or key fails on every corporate network, works everywhere else, and stays broken however many certificates are installed.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision Support triage gets one cheap first question: does the site load in a browser on that same machine? A yes sends the engineer to trust store configuration and away from the customer's firewall team.
- cost Adding the corporate root fixes the browser and leaves the root to be configured separately in each runtime: an environment variable for Node, another for Python, a keytool import for Java, and a code change for any Go client carrying its own RootCAs pool.
- constraint Pinning removes client-side remediation, so a vendor shipping a pinned app commits its enterprise customers to an allow-list request from their network team every time inspection scope changes.
The pairing is what you diagnose on. If the site loads in a browser on the customer's machine while your process throws a certificate verification error on that same host, the network is delivering bytes and the fault is which trust store your code consults [15].
Python code using `requests`, or anything else built on `certifi`, reads the certifi bundle instead of the system store, and `REQUESTS_CA_BUNDLE` or `SSL_CERT_FILE` overrides it [12]. Java keeps `cacerts`, managed with `keytool`, entirely separate from the OS [13]. Go does read system roots on Linux and macOS, though code that sets a custom `tls.Config` with its own `RootCAs` pool has opted out of them [14]. Of the four runtimes the post lists, three ignore the operating system store by default [1]. One root installed by the customer's administrator therefore fixes the browser and leaves each of those to be configured on its own.
Certificate Transparency requirements and most key-pinning checks are enforced for publicly trusted CAs and, by design, relaxed for locally added ones, because if they were not, corporate inspection would break the web for a large fraction of enterprise users [9]. Nothing is being exploited here: the chain validates because an administrator installed the root [8]. The proxy mints a certificate on the fly for whatever site was asked for, signed by that CA [6], so the padlock the customer screenshots is real, and it belongs to their employer [7]. It is also why they will tell you their internet is working [10].
According to the post, large organisations are often legally required to inspect traffic leaving their network, and have been doing it for twenty years [3]. The post sets out five failure modes and works through two of them, the trust store mismatch and certificate pinning, before its text ends [20].
You cannot fix pinning from the client. An app that pins a certificate or public key, common in mobile apps and in anything handling payments, has said it will accept one identity whatever the trust store contains, and an inspection proxy cannot present it because it does not hold the private key [17]. Installing more certificates changes nothing, and pinning is meant to be unfixable from the client side [18]. The remedy is administrative: the post argues that if you pin, you need a documented way for administrators to allow-list your domain from inspection, and your error message should say so. Most apps that pin fail with a generic network error [19].
What to watch
- A ticket where both Chrome and Firefox fail on the customer's machine. That rules out trust store scope and points at the network path itself.
- Any runtime changing its default to read the operating system trust store would remove the most common of these failures.
- The remaining three breakage modes the post promises but does not reach in the published text.