Fix it fast
Most likely: The registry URL npm is using does not match the hostname listed in the TLS certificate, often because of a wrong registry host, alias, proxy certificate, or scoped .npmrc mapping.
Confirm this is your error
Match the output and confirm you are troubleshooting the same failure.
npm ERR! code HOSTNAME_MISMATCH Check the cause
Run focused checks to identify what is failing in this environment.
npm config get registry
npm config get @your-scope:registry
npm config get proxy
npm config get https-proxy
openssl s_client -connect <registry-host>:443 -servername <registry-host> </dev/null | openssl x509 -noout -text Apply the safe fix
Use the smallest safe change that addresses the confirmed cause.
# Use the exact hostname covered by the registry certificate.
npm config set registry https://<correct-registry-host>/
npm ping
# If this is a private registry, fix the certificate SANs or the .npmrc hostname so they match. Verify it works
Repeat the relevant checks and confirm the original error is gone.
npm ping
npm install --verbose Avoid unsafe shortcuts
Keep security and data protections in place while troubleshooting.
- Do not leave
strict-ssl=falseas the fix, the hostname mismatch still exists. - Do not use registry aliases unless the certificate includes those aliases in Subject Alternative Name.
- Do not trust a proxy certificate for a different hostname.
Where the Request Failed
npm is telling you the request failed before it got a clean response back. Treat the connection path and the failing environment as the first suspects, not the package or image name.
Fix certificate trust and TLS
Start by proving the failing machine can reach the right host cleanly. Until DNS, routing, proxy, and trust look sane in that exact environment, retrying the install or pull is mostly noise.
Check system time and timezone (NTP). If it's wrong, fix it and retry.
Check for proxy settings:npm config get proxy and npm config get https-proxy
Check TLS config:npm config get strict-ssl and npm config get cafile
If you use scoped registries, verify .npmrc mapping (example: @your-scope:registry=...).
If you use a private registry, ensure the certificate includes the exact hostname you use in .npmrc.
If you control the registry/proxy, ensure it serves the full certificate chain (leaf + intermediates).
Inspect the served chain:openssl s_client -showcerts -connect <host>:443 -servername <host> </dev/null
Proper fix:trust the CA that is signing the certificate chain.
If you are behind a corporate TLS proxy, export the corporate root CA and configure npm:npm config set cafile /path/to/corp-ca.pem
In CI, prefer NODE_EXTRA_CA_CERTS=/path/to/corp-ca.pem so Node trusts the internal CA without changing global npm config.
Temporary diagnostics only:if you must confirm a trust issue, run npm --strict-ssl=false <command> once, then restore validation immediately.
Do not leave strict-ssl=false or NODE_TLS_REJECT_UNAUTHORIZED=0 in CI, shell profiles, or checked-in config. They disable certificate validation and increase MITM risk.
If you changed npm config for a one-off test, revert it immediately:npm config set strict-ssl true and unset NODE_TLS_REJECT_UNAUTHORIZED
Retry with npm --verbose and keep the full output for troubleshooting.
Manual certificate validation
Inspect SANs for the registry cert:openssl s_client -connect <host>:443 -servername <host> </dev/null | openssl x509 -noout -text
Confirm the hostname appears under Subject Alternative Name (SAN).
If you do a one-off SSL-bypass test, restore certificate validation immediately after it.
Why It Happens
Usually this comes down to the registry hostname does not match the certificate (CN/SAN mismatch), a proxy is presenting a certificate for a different hostname, or you are hitting the wrong registry host due to .npmrc scope mapping or an env override.
Prove the Failing Environment Can Reach It
Run npm ping and confirm it succeeds, and re-run the original command and confirm HOSTNAME_MISMATCH is gone.
How npm verifies TLS certificates
npm uses Node.js for HTTPS. Node verifies the certificate chain and checks that the certificate matches the hostname you requested. If the hostname does not match, the connection is rejected even if the certificate is otherwise trusted.
Prevent Repeat Connectivity Failures
To prevent this, avoid registry host aliases that do not match the deployed certificate, and keep .npmrc scope mappings explicit and reviewed.
Docs and source code
github.com/npm/cli/blob/417daa72b09c5129e7390cd12743ef31bf3ddb83/lib/utils/ping.js
This is the registry request path where npm talks to the network. DNS/TLS errors like this code are raised by Node/OS during this request. - GitHub
// used by the ping and doctor commands
const npmFetch = require('npm-registry-fetch')
module.exports = async (flatOptions) => {
const res = await npmFetch('/-/ping', { ...flatOptions, cache: false })
return res.json().catch(() => ({}))
}