Fehlermeldung
curl: (60) SSL certificate problem: unable to get local issuer certificate
Auch ausgegeben als
- curl: (60) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
- SSL certificate problem: unable to get local issuer certificate
curl auf OpenSSL-Basis (Linux, macOS Homebrew, Git for Windows) gibt diesen Text aus; neuere Releases (in unserem Test 8.22.0, während 8.14.1 noch den Text oben verwendete) formulieren ihn als „SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)“ und hängen den Prüfcode von OpenSSL an. Mit Schannel gebautes curl unter Windows meldet dieselbe Situation als „schannel: SEC_E_UNTRUSTED_ROOT (0x80090325)“, libcurl auf GnuTLS-Basis (von git unter Debian und Ubuntu verwendet) als „server verification failed: certificate signer not trusted“. Tools auf Basis von libcurl, etwa PHP und git, geben den Teil nach „(60) “ mit ihrem eigenen Präfix aus.
curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY (20)
Was der Fehler bedeutet
curl hat die Zertifikate des Servers erhalten, aber in seinem eigenen CA-Bundle nicht das Zertifikat gefunden, das das letzte Zertifikat der Kette ausgestellt hat. Das Zertifikat kann völlig gültig sein; curl kann es nur nicht mit einem Root-Zertifikat verketten, dem es vertraut, und verweigert deshalb die Verbindung (Exit-Code 60). Das fehlende Stück ist entweder ein Zwischenzertifikat, das der Server nicht mitgesendet hat, oder eine Root-CA, die dein Rechner nicht hat.
Warum der Fehler auftritt
Der Server sendet nur sein eigenes Zertifikat
häufigÖffentliche CAs signieren Serverzertifikate mit einem Zwischenzertifikat, und der Server muss dieses Zwischenzertifikat zusammen mit seinem Leaf-Zertifikat senden. Ein Server, der mit cert.pem statt fullchain.pem konfiguriert ist, funktioniert in Desktop-Browsern, die Zwischenzertifikate zwischenspeichern und fehlende nachladen; curl tut beides nicht und bleibt beim Leaf-Zertifikat stehen.
Das Zertifikat stammt von einer privaten oder firmeneigenen CA
häufigInterne Dienste, Staging-Umgebungen und Kubernetes-Ingresses verwenden oft Zertifikate von einer Firmen-CA oder einer selbst erstellten CA. Dieses Root-Zertifikat steht nicht im öffentlichen Bundle, das curl verwendet (/etc/ssl/certs/ca-certificates.crt unter Debian und Ubuntu), deshalb lässt sich nichts, was davon ausgestellt wurde, prüfen, bevor das Root-Zertifikat installiert ist.
Ein Proxy mit TLS-Inspektion signiert den Traffic neu
gelegentlichFirmen-Proxys und Endpoint-Security-Produkte (Zscaler, Netskope, Palo Alto und ähnliche) ersetzen das Zertifikat jeder Website durch eines, das ihre eigene CA ausgestellt hat. Der Browser vertraut dieser CA über den Zertifikatsspeicher des Betriebssystems, während curl, Container und WSL ein separates Bundle verwenden, in dem sie fehlt – deshalb scheitert jeder HTTPS-Aufruf auf dieselbe Weise.
Der Rechner hat kein brauchbares CA-Bundle
gelegentlichSlim- und Distroless-Container-Images werden ohne das Paket ca-certificates ausgeliefert, und alte Systeme haben Bundles, die älter sind als die heutigen Root-Zertifikate. Mit einem leeren oder veralteten Bundle scheitern selbst Zertifikate bekannter öffentlicher Websites mit dieser Meldung.
Die CA wurde einem Zertifikatsspeicher hinzugefügt, den dieses curl nicht liest
seltenJeder curl-Build liest ein bestimmtes Bundle: Das curl von Homebrew, eine conda-Umgebung und Git for Windows bringen jeweils ihr eigenes mit, und unter Windows gibt es sowohl Schannel- als auch OpenSSL-Builds. Eine CA, die dem Windows-Zertifikatsspeicher oder dem macOS-Schlüsselbund hinzugefügt wurde, erreicht nur die Builds, die diesen Speicher lesen.
So behebst du den Fehler
- 1.
Nachsehen, was der Server tatsächlich sendet
Liste die Zertifikate im Handshake auf. Erscheint nur eines (Tiefe 0) und ist sein Aussteller eine Zwischen-CA, ist die Konfiguration des Servers unvollständig und muss auf dem Server korrigiert werden. Endet die Kette bei einem firmeneigenen oder selbst erstellten Root-Zertifikat, fehlt dem Client dieses Root-Zertifikat.
bash # Which certificates does the server send, and who issued the last one? openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:' # 0 s:CN=api.example.com # i:C=US, O=Example Trust Services, CN=Example TLS Issuing CA <- leaf only: intermediate missing - 2.
Server korrigieren: vollständige Kette ausliefern
Konfiguriere den Webserver mit einem Bundle, das das Leaf-Zertifikat und danach jedes Zwischenzertifikat enthält. Das behebt den Fehler für alle Clients auf einmal, auch für mobile Apps und API-Clients, auf die du keinen Einfluss hast.
bash # Leaf first, then each intermediate in order; the root itself is optional cat api.example.com.crt intermediate.crt > fullchain.pem # nginx: ssl_certificate /etc/nginx/tls/fullchain.pem; # Apache: SSLCertificateFile /etc/apache2/tls/fullchain.pem # certbot: use live/<name>/fullchain.pem, never cert.pem - 3.
Private Root-CA im Zertifikatsspeicher des Systems installieren
Endet die Kette legitimerweise bei einem firmeneigenen oder internen Root-Zertifikat, füge dieses Root-Zertifikat dem Bundle des Betriebssystems hinzu. Hol es dir von deinem IT- oder Plattformteam oder direkt von der CA – niemals aus dem Zertifikat, das die fehlschlagende Verbindung präsentiert hat, denn genau dem kannst du noch nicht vertrauen.
bash # Debian, Ubuntu, Alpine (the file must end in .crt) sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates # RHEL, Fedora, Amazon Linux sudo cp corp-root-ca.pem /etc/pki/ca-trust/source/anchors/ sudo update-ca-trust - 4.
curl für einen Befehl oder eine Shell ein Bundle vorgeben
--cacert fügt Vertrauen für einen einzelnen Aufruf hinzu, ohne das System anzufassen; CURL_CA_BUNDLE legt das Bundle für jeden curl-Aufruf in der Umgebung fest. Die Datei kann mehrere PEM-Zertifikate enthalten.
bash curl --cacert corp-root-ca.pem https://api.example.com/ # or for every curl command in this shell (a file may hold several PEM certificates) export CURL_CA_BUNDLE=/opt/certs/corp-and-public-roots.pem - 5.
CA-Bundle in minimalen Containern installieren
Scheitern in einem Container sogar öffentliche Websites, hat das Image kein Bundle. Installiere ca-certificates im Image (oder kopiere /etc/ssl/certs/ca-certificates.crt aus einer Build-Stage), statt die Prüfung abzuschalten.
bash # Debian/Ubuntu-based images apt-get update && apt-get install -y --no-install-recommends ca-certificates # Alpine apk add --no-cache ca-certificates - 6.
Vorübergehende Diagnose: bestätigen, dass es ein Vertrauensproblem ist
-k (--insecure) schaltet die Zertifikatsprüfung ab; eine erfolgreiche Antwort beweist also nur, dass der Netzwerkpfad funktioniert und es beim Fehler um Vertrauen geht. Lass es nie in Skripten stehen: Mit -k kann jeder auf dem Übertragungsweg den Traffic lesen und verändern, einschließlich Zugangsdaten und heruntergeladenem Code.
bash # Diagnostic only: if this works, the problem is trust, not the network. curl -sS -k -o /dev/null -w '%{http_code}\n' https://api.example.com/
Verwandte Fehler
curl: (60) SSL certificate problem: self-signed certificate in certificate chaincurl (OpenSSL backend)curl: (60) SSL certificate problem: self-signed certificatecurl (OpenSSL backend)verify error:num=20:unable to get local issuer certificateOpenSSL CLI (openssl s_client / openssl verify)fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificat…git over HTTPS with libcurl + OpenSSL (Git for Windows default, macOS Homebrew, Alpine, RHEL)x509: certificate signed by unknown authorityGo crypto/x509