Zum Inhalt springen
ecdsa.com
Node.js tls / https / fetchNode.js crypto

Fehlermeldung

unable to verify the first certificate

Auch ausgegeben als

  • code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
  • UNABLE_TO_VERIFY_LEAF_SIGNATURE

Neuere Node.js-Releases (in unserem Test 24.22) hängen „; if the root CA is installed locally, try running Node.js with --use-system-ca“ an diese Meldung an. Bei fetch() erscheint sie als Ursache von „TypeError: fetch failed“; axios und got zeigen sie als Fehlermeldung mit demselben Code.

Node.js tls / https / fetch — code UNABLE_TO_VERIFY_LEAF_SIGNATURE (OpenSSL X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, 21)

Was der Fehler bedeutet

Node.js hat nur das eigene Zertifikat des Servers (das Leaf-Zertifikat) erhalten und seinen Aussteller nirgends gefunden: weder im Handshake noch unter den vertrauenswürdigen Root-Zertifikaten. Ohne den Aussteller kann Node.js nicht einmal die Signatur des Leaf-Zertifikats prüfen, daher „the first certificate“. Fast immer vergisst der Server, sein Zwischenzertifikat mitzusenden; Browser kaschieren das, indem sie Zwischenzertifikate herunterladen, Node.js tut das nie.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Prüfen, wie viele Zertifikate der Server sendet

    Erscheint nur das Zertifikat auf Tiefe 0 und ist sein Aussteller eine Zwischen-CA, gehört die Korrektur auf den Server.

    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.

    Vollständige Kette ausliefern

    Gib dem Server ein Bundle mit dem Leaf-Zertifikat und danach allen Zwischenzertifikaten. Bei Node.js-Servern ist das die Option cert, bei nginx ssl_certificate, bei Cloud-Load-Balancern das Feld für die Zertifikatskette.

    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.

    Wenn du den Server nicht ändern kannst: Zwischenzertifikat auf dem Client hinzufügen

    NODE_EXTRA_CA_CERTS akzeptiert auch Zwischenzertifikate und wird einmal beim Start des Prozesses gelesen. Behebe das Problem besser auf dem Server: Jeder andere Client (mobile Apps, Partner) hat dasselbe Problem.

    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.

    Vorübergehende Diagnose: Prüfung für einen Lauf abschalten

    NODE_TLS_REJECT_UNAUTHORIZED=0 schaltet die Zertifikatsprüfung für jede TLS-Verbindung im Prozess ab und gibt eine Warnung aus. Verwende das nur, um die Diagnose zu bestätigen; in Produktion kann damit jeder auf dem Übertragungsweg den Traffic lesen und verändern.

    bash
    # Temporary diagnostic only: disables certificate verification for the whole process
    NODE_TLS_REJECT_UNAUTHORIZED=0 node app.js

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen