Mensagem de erro
Hostname/IP does not match certificate's altnames: Host: api.example.com. is not in the cert's altnames: DNS:www.example.com
Também aparece 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
O host e a lista de altnames são preenchidos a cada falha. Para endereços IP, o texto é “Hostname/IP does not match certificate's altnames: IP: <address> is not in the cert's list: <entries>”. O npm mostra o erro como “npm error code ERR_TLS_CERT_ALTNAME_INVALID”.
Node.js tls.checkServerIdentity() — code ERR_TLS_CERT_ALTNAME_INVALID
O que significa
A cadeia de certificados é confiável, mas tls.checkServerIdentity() não encontrou nenhum Subject Alternative Name que corresponda ao host ao qual o Node.js se conectou. A mensagem mostra os dois lados: o host que você pediu e os nomes que o certificado realmente contém, então a divergência fica evidente à primeira vista. O Common Name é ignorado quando o certificado tem uma extensão SAN.
Por que acontece
O certificado não lista este nome
comumUm certificado para www.example.com não cobre api.example.com nem o domínio sem www; um curinga cobre só um nível do nome.
Conexão por IP, localhost ou alias de contêiner
comumURLs como https://127.0.0.1:8443 ou https://backend:443 dentro do docker-compose pedem nomes que o certificado não contém; endereços IP precisam de entradas de IP no SAN.
Só o cabeçalho Host foi alterado, e não o nome usado no TLS
ocasionalDefinir headers.host (o cabeçalho Host) com o nome correto em uma conexão por IP não muda o que o Node.js verifica; é a opção servername (ou o host da URL) que decide qual nome é conferido e enviado como SNI.
O servidor retornou o próprio certificado padrão
ocasionalUm proxy reverso sem configuração para este nome responde com o certificado de outro site.
Como corrigir
- 1.
Listar os nomes do certificado
Compare o subjectAltName com o host ao qual você se conecta.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName - 2.
Reemitir com todos os nomes em uso
Inclua todos os nomes DNS e, onde os clientes se conectam por endereço, as entradas de 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.
Definir servername ao conectar por endereço
Mantenha o nome do certificado em servername (e no cabeçalho Host) e conecte-se ao endereço; assim a verificação usa o nome correto em vez de ser desativada.
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.
Exceção restrita com checkServerIdentity
Para um host legado cujo certificado ainda não pode ser reemitido, mapeie um único alias conhecido para o nome do certificado e delegue para tls.checkServerIdentity(). Nunca retorne undefined incondicionalmente: isso desativa completamente a verificação do nome.
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), });
Erros 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)