Mensagem de erro
unable to verify the first certificate
Também aparece como
- code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
- UNABLE_TO_VERIFY_LEAF_SIGNATURE
Versões recentes do Node.js (24.22 no nosso teste) acrescentam “; if the root CA is installed locally, try running Node.js with --use-system-ca” a esta mensagem. Com fetch(), ela aparece como a causa de “TypeError: fetch failed”; o axios e o got a exibem como a mensagem de erro, com o mesmo código.
Node.js tls / https / fetch — code UNABLE_TO_VERIFY_LEAF_SIGNATURE (OpenSSL X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, 21)
O que significa
O Node.js recebeu só o certificado do próprio servidor (o certificado folha) e não encontrou o emissor dele em lugar nenhum: nem no handshake, nem entre as raízes confiáveis. Sem o emissor, ele não consegue nem verificar a assinatura do certificado folha — daí “the first certificate”. Quase sempre o servidor deixa de enviar o certificado intermediário; os navegadores mascaram o problema baixando os intermediários, mas o Node.js nunca faz isso.
Por que acontece
O servidor não envia o certificado intermediário
comumUm arquivo de certificado que contém só o certificado folha (cert.pem em vez de fullchain.pem, ou um certificado de balanceador de carga carregado sem a cadeia). Mesmo com a raiz correta marcada como confiável, o Node.js não consegue ligar o certificado folha à raiz, como mostra a reprodução.
Uma CA privada emitiu o certificado folha, e nada na cadeia é conhecido
comumServiços internos que servem apenas o próprio certificado, emitido por uma CA da empresa ou criada por conta própria, produzem o mesmo código: o Node.js não conhece o emissor nem nada acima dele.
O intermediário está no arquivo, mas não é usado
ocasionalAlguns servidores enviam só o primeiro certificado de um arquivo ou esperam a cadeia em uma configuração separada (SSLCertificateChainFile em versões antigas do Apache, um campo separado para a cadeia em balanceadores de carga na nuvem). O intermediário existe no disco, mas nunca chega ao cliente.
Como corrigir
- 1.
Verificar quantos certificados o servidor envia
Se aparecer só a profundidade 0 e o emissor desse certificado for uma CA intermediária, a correção deve ser feita no servidor.
bash openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' # Only " 0 s:" present, with an i: that is an intermediate -> the server must send that intermediate - 2.
Servir a cadeia completa
Configure o servidor com um bundle que tenha o certificado folha seguido de todos os intermediários. Em servidores Node.js, é a opção cert; no nginx, ssl_certificate; em balanceadores de carga na nuvem, o campo da cadeia de certificados.
js // Node.js HTTPS server: pass leaf + intermediates as the cert import https from "node:https"; import fs from "node:fs"; https.createServer({ key: fs.readFileSync("server.key"), cert: fs.readFileSync("fullchain.pem"), // leaf first, then intermediate(s) }, handler).listen(443); - 3.
Se não puder alterar o servidor: adicionar o intermediário no cliente
A variável NODE_EXTRA_CA_CERTS também aceita certificados intermediários e é lida uma vez, na inicialização do processo. Prefira corrigir o servidor: todos os outros clientes (aplicativos móveis, parceiros) têm o mesmo problema.
bash # When you cannot fix the server: trust the missing intermediate on the client too NODE_EXTRA_CA_CERTS=/etc/ssl/certs/issuing-ca.pem node app.js - 4.
Diagnóstico temporário: desativar a verificação em uma execução
NODE_TLS_REJECT_UNAUTHORIZED=0 desliga as verificações de certificado em todas as conexões TLS do processo e imprime um aviso. Use apenas para confirmar o diagnóstico; em produção, isso permite que qualquer um no caminho leia e altere o tráfego.
bash # Temporary diagnostic only: disables certificate verification for the whole process NODE_TLS_REJECT_UNAUTHORIZED=0 node app.js
Erros relacionados
unable to get local issuer certificateNode.js tls / https / fetchself-signed certificate in certificate chainNode.js tls / https / fetchnpm error code UNABLE_TO_VERIFY_LEAF_SIGNATUREnpm (Node.js)verify error:num=21:unable to verify the first certificateOpenSSL CLI (openssl s_client)curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)