npm HTTPS request failed: self-signed path root
The npm HTTPS wrapper ties a self-signed-path refusal to the selected request hop. It is not proof that every self-signed certificate is defective, nor that the package itself is unavailable. Compare the actual npm process's approved CA selection with that hop's public path before changing a proxy, registry or application bundle. Match this output from npm, then continue with sourced, read-only checks.
- Confidence
- high
- Platforms
- linux · macos · windows
- Verified
- 2026-10-01
Signature matched locally
npm HTTPS request failed: self-signed path rootOneLiners matches this pattern in your browser. Your pasted output is not stored or indexed.
What usually produces this signal
- A peer-supplied self-signed path root is not in the client's effective approved CA set. Sending that root does not make it trusted; our actual loopback wrapper was produced with an unrelated explicit cafile.
- The original npm command uses a different project/user/environment/CLI trust selection from a successful browser or standalone Node client. Node requests supplying explicit ca can replace default roots rather than merely extend them.
- A proxy, redirect or virtual host supplies an unexpected path. Establish its authorization and original hostname before accepting credentials or copying a peer's chain into a trust file; a successful request to another host cannot settle this refusal.
Collect evidence before changing the system
Compare the original npm CA selection rather than another application's success
# Run where the failed command executes; metadata only.
node -p "JSON.stringify({node:process.versions.node,openssl:process.versions.openssl})"
npm config get strict-ssl
npm config get cafile
# Privately inspect explicit ca and process-start extra-CA configuration.
# Do not dump the environment, npm configuration, proxy URLs or registry tokens.Expected signal: The original npm logger contains the self-signed-chain request reason, not a self-signed-leaf code or an HTTP denial. Metadata identifies the actual process/config scope under review; a different verifier's success is only a comparison.
NODE_EXTRA_CA_CERTS is read when Node starts; changing it inside an already running process is not a demonstrated fix. Explicit ca selection can ignore that extended default trust. Do not set strict-ssl=false, rejectUnauthorized=false or NODE_TLS_REJECT_UNAUTHORIZED=0.
Cross-check this hop's chain without converting a received root into approval
# Public exports only; verify the ORIGINAL hop's hostname and approved root policy.
openssl verify -no-CApath -no-CAstore -CAfile approved-roots.pem -untrusted captured-chain.pem -purpose sslserver -verify_hostname registry.example.test leaf.pemExpected signal: The explicit-root check preserves the actual self-signed-path error/depth or validates the owner's intended chain. In the loopback case, selecting the independently known signing root allowed a verified GET while the same peer chain and strict-ssl setting stayed unchanged.
This offline check is not proof of npm proxy routing or live served configuration. A peer-provided root stays an untrusted path input unless independently approved. Preserve the failed request stage and distinguish any subsequent HTTP/application error from TLS success.
Check the input against the result
Input and result
npm error request to https://127.0.0.1:<port>/-/ping failed, reason: self-signed certificate in certificate chain
# Actual native request-level excerpt. Fixture deliberately supplies its root.
# Client initially trusts only an unrelated root; strict-ssl remains true.request_reason=self-signed certificate in certificate chain
native_code=SELF_SIGNED_CERT_IN_CHAIN
untrusted_path_exit=1 failed_http_gets=0
independently_known_root_exit=0 verified_http_gets=1
request_authorization_headers=0 global_ca_changes=0Both native attempts used an empty fixture user/global configuration and credential-free loopback ping. Only the process-scoped cafile changed between refusal and success. No corporate proxy, artifact download, system CA import or real authentication was exercised.
Correct only the demonstrated cause
Escalate an intended private path to its CA owner and correct only the demonstrated process-scoped trust or server-chain selection. If the issuer or route is unexpected, investigate it rather than trusting the downloaded root or changing every project's settings.
Verify: The same npm command reaches the original approved hop with ordinary TLS/name/time checks and the reviewed configuration source. Independently verify other hops and application results; absence of this TLS wrapper alone does not prove successful deployment or installation.
Stop if: The CA is unauthenticated, the failing process is not the one being changed, a globally disabled check is proposed, or a self-signed leaf/name/expiry error is being conflated with this request's path-root failure.