What
Claude Code loads root certificates, which decide which secure (TLS) connections it trusts. It takes them from three sources: the certificates bundled with it, the operating system's store, and a file named by the NODE_EXTRA_CA_CERTS environment variable, which users set to add their own certificates. The loader (Xn) now checks every certificate from all three sources against a built-in deny list:
- The deny list holds four SHA-256 certificate fingerprints, each paired with a public-key hash, and a certificate matching either is blocked.
- Blocked certificates are dropped. PEM blocks that cannot be parsed are checked for blocked certificates too, and blocks nested more than 8 deep (
me = 8) are ignored. - In the
NODE_EXTRA_CA_CERTSfile, a block holding a deny-listed root is skipped and an error is written to the console, for example: "Claude Code ignored a block in the NODE_EXTRA_CA_CERTS file: the block holds a root certificate on the CLI's deny list, in a form Claude Code could not read. The other certificates in the file are still used." If a blocked certificate is in a form that cannot be cut out, the whole file is ignored. - If filtering leaves the list empty, loading falls back to the bundled roots. If every bundled root is blocked, startup throws an error telling the user to update.
Separately, when stores=system is in use but the system CA API is unavailable, the loader no longer stops early with "deferring to runtime". It now logs that it is using bundled roots and loads them.
Why
This changes which root certificates Claude Code trusts. If you use a custom certificate file, for example behind a corporate proxy, some of its certificates, or the whole file, may now be ignored. When that happens, Claude Code writes an error message to the console. If you rely on the system certificate store and its API is missing, Claude Code now uses its bundled roots instead of leaving the choice to the runtime.