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
Der Server sendet sein Zwischenzertifikat nicht mit
häufigEine Zertifikatsdatei, die nur das Leaf-Zertifikat enthält (cert.pem statt fullchain.pem oder ein Zertifikat, das ohne Kette in einen Load Balancer hochgeladen wurde). Selbst wenn dem richtigen Root-Zertifikat vertraut wird, kann Node.js keine Brücke zwischen Leaf- und Root-Zertifikat schlagen, wie die Reproduktion zeigt.
Eine private CA hat das Leaf-Zertifikat ausgestellt, und nichts in der Kette ist bekannt
häufigInterne Dienste, deren Zertifikat von einer Firmen-CA oder einer selbst erstellten CA stammt und die es allein ausliefern, erzeugen denselben Code: Node.js kennt weder den Aussteller noch irgendein Zertifikat, das in der Kette darüber liegt.
Das Zwischenzertifikat steht in der Datei, wird aber nicht verwendet
gelegentlichManche Server senden nur das erste Zertifikat einer Datei oder erwarten die Kette in einer separaten Einstellung (SSLCertificateChainFile in alten Apache-Versionen, ein eigenes Feld für die Kette bei Cloud-Load-Balancern). Das Zwischenzertifikat liegt auf der Festplatte, erreicht den Client aber nie.
So behebst du den Fehler
- 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.
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.
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.
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
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)