Mensaje de error
Hostname/IP does not match certificate's altnames: Host: api.example.com. is not in the cert's altnames: DNS:www.example.com
También se muestra como
- Hostname/IP does not match certificate's altnames: IP: 127.0.0.1 is not in the cert's list:
- code: 'ERR_TLS_CERT_ALTNAME_INVALID'
- ERR_TLS_CERT_ALTNAME_INVALID
El host y la lista de altnames se rellenan con los valores de cada fallo. Para direcciones IP, el texto es «Hostname/IP does not match certificate's altnames: IP: <address> is not in the cert's list: <entries>». npm lo muestra como «npm error code ERR_TLS_CERT_ALTNAME_INVALID».
Node.js tls.checkServerIdentity() — code ERR_TLS_CERT_ALTNAME_INVALID
Qué significa
La cadena de certificados es de confianza, pero tls.checkServerIdentity() no encontró ningún nombre alternativo del sujeto (SAN) que coincida con el host al que se conectó Node.js. El mensaje muestra ambos lados: el host solicitado y los nombres que contiene realmente el certificado, así que la discrepancia se ve de un vistazo. El nombre común se ignora cuando el certificado tiene una extensión SAN.
Por qué ocurre
El certificado no incluye este nombre
frecuenteUn certificado para www.example.com no cubre api.example.com ni el dominio sin subdominio; los comodines cubren una sola etiqueta.
Conexión por IP, por localhost o por un alias de contenedor
frecuenteLas URL como https://127.0.0.1:8443 o https://backend:443 dentro de docker-compose piden nombres que el certificado no contiene; las IP necesitan entradas SAN de tipo IP.
Solo se cambió el encabezado Host, no el nombre TLS
ocasionalPoner el nombre correcto en headers.host mientras te conectas por IP no cambia lo que verifica Node.js; la opción servername (o el host de la URL) decide qué nombre se comprueba y se envía como SNI.
El servidor devolvió su certificado predeterminado
ocasionalUn proxy inverso sin configuración para este nombre responde con el certificado de otro sitio.
Cómo solucionarlo
- 1.
Listar los nombres del certificado
Compara subjectAltName con el host al que te conectas.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName - 2.
Volver a emitir el certificado con todos los nombres en uso
Añade todos los nombres DNS y, donde los clientes se conecten por dirección, las entradas de tipo IP.
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,DNS:www.example.com,IP:10.0.0.5" - 3.
Establecer servername al conectarse por dirección
Deja el nombre del certificado en servername (y en el encabezado Host) y conéctate a la dirección; así la verificación usa el nombre correcto en lugar de quedar desactivada.
js // Connect to an address but verify the certificate's real name (also sent as SNI) import https from "node:https"; https.get({ host: "10.0.0.5", port: 443, path: "/", servername: "api.example.com", headers: { host: "api.example.com" } }, (res) => res.resume()); - 4.
Excepción acotada con checkServerIdentity
Para un host heredado cuyo certificado todavía no se puede volver a emitir, asigna un único alias conocido al nombre del certificado y delega en tls.checkServerIdentity(). Nunca devuelvas undefined de forma incondicional: eso desactiva por completo la comprobación del nombre.
js // Narrow exception for a host you cannot reissue: accept one extra name, keep all other checks import https from "node:https"; import tls from "node:tls"; const agent = new https.Agent({ checkServerIdentity: (host, cert) => tls.checkServerIdentity(host === "legacy-alias.internal" ? "api.example.com" : host, cert), });
Errores relacionados
npm error code ERR_TLS_CERT_ALTNAME_INVALIDnpm (Node.js)x509: certificate is valid for example.com, not api.example.comGo crypto/x509curl: (60) SSL: no alternative certificate subject name matches target hostname…curl (OpenSSL backend)[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch,…Python ssl module (OpenSSL host check)