Fehlermeldung
invalid peer certificate: UnknownIssuer
Auch ausgegeben als
- InvalidCertificate(UnknownIssuer)
reqwest gibt die Meldung am Ende seiner Kette von Ursachen aus: „error sending request for url (…): client error (Connect): invalid peer certificate: UnknownIssuer“; die Debug-Ausgabe zeigt InvalidCertificate(UnknownIssuer). ureq gibt „io: invalid peer certificate: UnknownIssuer“ aus. Native Binärdateien, die auf rustls aufbauen (pnpm 12, viele CLIs), zeigen denselben Text.
rustls (via reqwest, ureq, hyper-rustls, tonic) — rustls::Error::InvalidCertificate(CertificateError::UnknownIssuer)
Was der Fehler bedeutet
rustls konnte das Zertifikat des Servers mit keinem der Vertrauensanker, mit denen es konfiguriert wurde, zu einer Kette verbinden. UnknownIssuer ist der einzige Code, mit dem rustls jedes Scheitern beim Pfadaufbau meldet: eine private CA oder die CA eines Proxys, ein fehlendes Zwischenzertifikat oder ein selbstsigniertes Zertifikat. Welche Root-Zertifikate als vertrauenswürdig gelten, hängt davon ab, wie das Crate gebaut wurde: mit dem Plattform-Verifier (Zertifikatsspeicher des Betriebssystems), mit rustls-native-certs (Root-Zertifikate des Betriebssystems, beim Start geladen) oder mit webpki-roots (einkompilierte Liste von Mozilla).
Warum der Fehler auftritt
Eine Firmen-CA oder eine private CA
häufigDie Kette des Servers endet bei einem Root-Zertifikat, das nicht zu den konfigurierten Vertrauensankern gehört – typisch für interne Dienste und Proxys mit TLS-Inspektion.
Der Client vertraut nur einkompilierten öffentlichen Root-Zertifikaten
häufigCrates, die mit webpki-roots gebaut sind, ignorieren den Zertifikatsspeicher des Betriebssystems vollständig, sodass ein von der IT installiertes Root-Zertifikat nie greift. Der standardmäßige Plattform-Verifier von reqwest 0.13 nutzt dagegen den Zertifikatsspeicher des Betriebssystems (wie die Reproduktion nach update-ca-certificates bestätigt hat).
Der Server sendet sein Zwischenzertifikat nicht
gelegentlichrustls lädt fehlende Zwischenzertifikate nicht nach; ein Server, der nur das Leaf-Zertifikat sendet, scheitert mit UnknownIssuer, selbst wenn das Root-Zertifikat vertrauenswürdig ist.
Ein selbstsigniertes Serverzertifikat
gelegentlichrustls meldet auch selbstsignierte Zertifikate als UnknownIssuer; vertraue dem Zertifikat für diesen Client als Root-Zertifikat oder ersetze es.
So behebst du den Fehler
- 1.
Root-Zertifikat zum Client hinzufügen
ClientBuilder::add_root_certificate fügt einen Vertrauensanker hinzu und behält die vollständige Prüfung bei (Namen, Gültigkeitsdaten).
rust // Trust a private root for this client (in addition to the default roots) let pem = std::fs::read("corp-root-ca.pem")?; let client = reqwest::Client::builder() .add_root_certificate(reqwest::Certificate::from_pem(&pem)?) .build()?; - 2.
Root-Zertifikat im Zertifikatsspeicher des Systems installieren
Mit dem Plattform-Verifier (Standard in reqwest 0.13) gelten die Root-Zertifikate im Zertifikatsspeicher des Betriebssystems als vertrauenswürdig; unter Linux genügt update-ca-certificates.
bash # reqwest 0.13 verifies with the platform verifier: install the root in the OS store sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates - 3.
Prüfen, welche Quelle für Root-Zertifikate einkompiliert ist
cargo tree zeigt, ob webpki-roots oder rustls-native-certs verwendet wird; stelle die Features um, wenn der Zertifikatsspeicher des Betriebssystems gelten muss.
bash # Which root source is compiled into this binary? (a crate that is absent reports no match) cargo tree -e features -i rustls-platform-verifier # OS verifier (reqwest 0.13 default) cargo tree -e features -i rustls-native-certs # OS roots loaded at start-up cargo tree -e features -i webpki-roots # Mozilla roots compiled in, OS store ignored - 4.
Eigener Server: Zwischenzertifikat mitsenden
Steht im Handshake nur ein einziges Zertifikat, dessen Aussteller eine Zwischen-CA ist, dann ist die Konfiguration des Servers unvollständig.
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:'
Verwandte Fehler
invalid peer certificate: certificate expired: verification timerustls 0.23 (via reqwest, ureq, hyper-rustls)invalid peer certificate: certificate not valid for name "api.example.com"; cer…rustls 0.23 (via reqwest, ureq, hyper-rustls)Error: ERR_PNPM_RESOLVING_NPM_RESOLVER_NETWORK_ERRORpnpm 12 (native binary, rustls)x509: certificate signed by unknown authorityGo crypto/x509