• Node.js
  • Exact text checked with the real tool

ERR_TLS_CERT_ALTNAME_INVALID

Also seen in: npm, yarn, axios, fetch (undici), Electron

In one sentence

The certificate is trusted, but the hostname or IP address you connected to is not among the names in its Subject Alternative Name list.

Where you see it

In Node.js HTTPS clients (https, fetch, axios, got) and in npm, after the certificate chain was accepted. The code is listed in the Node.js errors documentation; the check is done by tls.checkServerIdentity().

TypeError: fetch failed
    ...
  [cause]: Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: api.internal.example.com. is not in the cert's altnames: DNS:www.example.com
    ...
    code: 'ERR_TLS_CERT_ALTNAME_INVALID',
    reason: "Host: api.internal.example.com. is not in the cert's altnames: DNS:www.example.com",
    host: 'api.internal.example.com',

When you connect by IP address and the certificate has no IP entries, the message ends differently:

Hostname/IP does not match certificate's altnames: IP: 10.0.0.5 is not in the cert's list: 

npm shows the same code: npm error code ERR_TLS_CERT_ALTNAME_INVALID.

What it means

A certificate lists the names it is valid for in its Subject Alternative Name (SAN) extension. Node.js compares the host you connected to with that list. The message shows both sides: your host after Host: and the certificate’s names after altnames:. The certificate is genuine but issued for other names, so Node.js refuses it.

Likely causes

You use a name the certificate does not list

A short internal name, a load balancer’s DNS name, a container name such as api in Docker Compose, or localhost. The message already shows the certificate’s names; to see the full certificate:

openssl s_client -connect api.internal.example.com:443 -servername api.internal.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName

Fix: use one of the listed names in your URL, or have the certificate reissued with every name clients use. For a private CA, put all names in the request:

openssl req -new -key server.key -subj "/CN=api.internal.example.com" \
  -addext "subjectAltName=DNS:api.internal.example.com,DNS:api" -out server.csr

You connect by IP address

An IP address only matches an IP Address: entry in the SAN list. Use the DNS name, or reissue the certificate with an IP: entry. If you must connect to an IP but verify a name, set servername and keep the check:

https.get({ host: '10.0.0.5', servername: 'api.internal.example.com', path: '/' })

Node.js then sends api.internal.example.com in SNI and checks the certificate against that name.

The server sends the wrong certificate

A server with several sites chooses the certificate by the name in SNI and falls back to a default one. If the altnames in the message belong to a different site, the server is not configured for your name. Compare:

openssl s_client -connect api.internal.example.com:443 -servername api.internal.example.com </dev/null 2>/dev/null | openssl x509 -noout -ext subjectAltName

Add a matching server_name block in nginx, a ServerName virtual host in Apache, or a hostname binding in IIS, each with the right certificate. On Kubernetes, check that the Ingress tls.hosts list contains the name.

A wildcard does not cover this name

*.example.com matches exactly one label. It does not match example.com or v2.api.example.com. Add those names as separate SAN entries.

The certificate has no DNS name in its SAN

If the reason reads Host: api.internal.example.com. is not cert's CN: www.example.com, the certificate has no DNS name in its SAN list (no SAN at all, or only IP addresses), so Node.js fell back to the Common Name. Browsers and Go never do that. Reissue the certificate with every hostname as a DNS entry in the SAN list.

Check yours

Try it: Hostname matcherOpen the full tool

Runs in your browser. Nothing you paste is sent anywhere.

What do you have?

Paste the server’s certificate and type the hostname from your URL. The matcher shows which SAN entries match and why the others do not.

Learn why

In the gameLevel 9: Names and jobsName Registry, Keystone. In development

Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.

Last reviewed Edition 0.9