Message d’erreur
unable to verify the first certificate
Également affiché sous la forme
- code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
- UNABLE_TO_VERIFY_LEAF_SIGNATURE
Les versions récentes de Node.js (24.22 dans notre test) ajoutent « ; if the root CA is installed locally, try running Node.js with --use-system-ca » à ce message. Avec fetch(), il apparaît comme cause de « TypeError: fetch failed » ; axios et got l’affichent comme message d’erreur, avec le même code.
Node.js tls / https / fetch — code UNABLE_TO_VERIFY_LEAF_SIGNATURE (OpenSSL X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, 21)
Ce que cela signifie
Node.js n’a reçu que le certificat propre au serveur (le certificat feuille) et n’a trouvé son émetteur nulle part : ni dans le handshake ni parmi ses racines de confiance. Sans l’émetteur, il ne peut même pas vérifier la signature du certificat feuille, d’où « the first certificate ». Presque toujours, le serveur oublie d’envoyer son certificat intermédiaire ; les navigateurs masquent le problème en téléchargeant les certificats intermédiaires, ce que Node.js ne fait jamais.
Pourquoi cela se produit
Le serveur n’envoie pas son certificat intermédiaire
fréquenteUn fichier de certificat qui ne contient que le certificat feuille (cert.pem au lieu de fullchain.pem, ou un certificat de répartiteur de charge importé sans la chaîne). Même si la bonne racine est approuvée, Node.js ne peut pas relier le certificat feuille à la racine, comme le montre la reproduction.
Une AC privée a émis le certificat feuille, et rien dans la chaîne n’est connu
fréquenteLes services internes dont le certificat provient d’une AC d’entreprise ou faite maison, et qui le servent seul, produisent le même code : Node.js ne connaît ni l’émetteur ni rien de ce qui se trouve au-dessus.
Le certificat intermédiaire est dans le fichier, mais n’est pas utilisé
occasionnelleCertains serveurs n’envoient que le premier certificat d’un fichier, ou attendent la chaîne dans un paramètre distinct (SSLCertificateChainFile dans les anciennes versions d’Apache, un champ de chaîne distinct dans les répartiteurs de charge cloud). Le certificat intermédiaire existe sur le disque, mais n’atteint jamais le client.
Comment corriger l’erreur
- 1.
Vérifier combien de certificats le serveur envoie
Si seule la profondeur 0 apparaît et que son émetteur est une AC intermédiaire, la correction doit se faire sur le serveur.
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 la chaîne complète
Fournissez au serveur un fichier contenant le certificat feuille suivi de tous les certificats intermédiaires. Pour les serveurs Node.js, il s’agit de l’option cert ; pour nginx, de ssl_certificate ; pour les répartiteurs de charge cloud, du champ de chaîne de certificats.
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.
Si vous ne pouvez pas modifier le serveur : ajouter le certificat intermédiaire côté client
NODE_EXTRA_CA_CERTS accepte aussi les certificats intermédiaires et n’est lu qu’une fois, au démarrage du processus. Corrigez de préférence le serveur : tous les autres clients (applications mobiles, partenaires) rencontrent le même problème.
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.
Diagnostic temporaire : désactiver la vérification pour une seule exécution
NODE_TLS_REJECT_UNAUTHORIZED=0 désactive les contrôles de certificat pour chaque connexion TLS du processus et affiche un avertissement. Ne l’utilisez que pour confirmer le diagnostic ; en production, il permet à n’importe qui sur le chemin de lire et de modifier le trafic.
bash # Temporary diagnostic only: disables certificate verification for the whole process NODE_TLS_REJECT_UNAUTHORIZED=0 node app.js
Erreurs associées
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)