Read the deepest causeThe outer message identifies the endpoint. DNS, refused TCP, TLS validation, and proxy routing live in the chained cause.

One message. Four boundaries.

01 · DNSName never resolvesENOTFOUND · EAI_AGAIN

Resolver, VPN, split DNS.

02 · TCPNo route completesECONNREFUSED · ETIMEDOUT

Firewall, proxy, endpoint.

03 · TLSChain is not trustedSELF_SIGNED_CERT_IN_CHAIN

Inspection CA, trust store.

04 · HTTPA server answered401 · 403 · 429 · 5xx

Credential, policy, quota.

Prove Node egress without a key.

Same shellcredential-free fetchfetch('https://api.deepseek.com')
Any HTTP statustransport worksDNS + TCP + TLS + proxy reached a server
node -e "fetch('https://api.deepseek.com')
  .then(r => console.log('HTTP', r.status))
  .catch(e => { console.error(e, e.cause); process.exit(1) })"

Repair the boundary that failed.

AEnable approved proxy routingNODE_USE_ENV_PROXY=1

Feature-test the installed Node minor. Keep localhost in NO_PROXY.

BExtend CA trust at startupNODE_EXTRA_CA_CERTS=…pem

Use the administrator-issued certificate. Restart the Host.

CRoute the HTTP status401 ≠ 403 ≠ 429

Once a server answered, stop changing proxy and CA settings.

Keep the two connections separate.

Browser → HostOrigin, Host header, loopbackA local 403 belongs here.
Host → ProviderDNS, proxy, CA, APIfetch failed belongs here.

Prove the repaired path.

  1. ProbeNode reaches HTTP
  2. Trustno TLS error
  3. Loopbackstays local
  4. Modelstreams terminal output
  5. Restartbehavior persists

Source-backed

Use the full evidence worksheet.

Open the runbook