Aller au contenu
ecdsa.com
Node.js tls / https / fetchNode.js crypto

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

Comment corriger l’erreur

  1. 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. 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. 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. 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

Parcourir toute la base de données des erreurs de signature