Fehlermeldung
invalid peer certificate: certificate not valid for name "api.example.com"; certificate is only valid for DnsName("www.example.com")
Der erwartete Name und die vorgewiesene Liste werden pro Fehlerfall eingesetzt; IP-Adressen erscheinen als IpAddress(…). Frühere rustls-Releases gaben nur den Namen der Variante aus („invalid peer certificate: NotValidForName“).
rustls 0.23 (via reqwest, ureq, hyper-rustls) — CertificateError::NotValidForNameContext
Was der Fehler bedeutet
Die Kette ist vertrauenswürdig, aber der Name, zu dem der Client eine Verbindung aufgebaut hat, steht nicht unter den Subject Alternative Names des Zertifikats. rustls 0.23 nennt beides: den erwarteten Namen und jeden Namen, den das Zertifikat vorweist (Einträge vom Typ DnsName und IpAddress), wodurch die Abweichung offensichtlich wird.
Warum der Fehler auftritt
Das Zertifikat deckt diesen Namen nicht ab
häufigEine andere Subdomain, die Domain ohne Subdomain oder ein umbenannter Dienst fehlt in der SAN-Liste; Wildcards decken nur ein einzelnes Label ab.
Verbindung über eine IP-Adresse oder einen internen Alias
häufigDienstnamen (Kubernetes, docker-compose) oder bloße Adressen, für die das Zertifikat nie ausgestellt wurde.
Der Server hat sein Standardzertifikat gesendet
gelegentlichEin Proxy ohne Konfiguration für den angefragten Namen liefert das Zertifikat einer anderen Website aus.
So behebst du den Fehler
- 1.
Vorgewiesene Namen mit der URL vergleichen
Die Meldung listet sie bereits auf; openssl bestätigt, was der Server sendet.
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName - 2.
Adresse überschreiben, nicht den Namen
ClientBuilder::resolve von reqwest bindet einen Hostnamen fest an eine Socket-Adresse, sodass die Prüfung weiterhin den Namen des Zertifikats verwendet.
rust // Keep the certificate's name in the URL and send the connection to a specific address let addr: std::net::SocketAddr = "10.0.0.5:443".parse()?; let client = reqwest::Client::builder().resolve("www.example.com", addr).build()?; let resp = client.get("https://www.example.com/health").send().await?; - 3.
Mit allen verwendeten Namen neu ausstellen
Nimm die fehlenden DNS-Namen (oder IP-Einträge) in das Zertifikat auf.
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,DNS:www.example.com"