Message d’erreur
tls: failed to verify certificate: x509: certificate signed by unknown authority
Go crypto/tls (Go ≥ 1.20) — wrapping x509 verification errors
Ce que cela signifie
Depuis Go 1.20, les échecs du handshake TLS enveloppent l’erreur x509 sous-jacente dans le préfixe « tls: failed to verify certificate: », si bien que les journaux montrent à la fois la couche (handshake TLS) et la cause racine (échec de la construction de la chaîne). Le suffixe varie (autorité inconnue, certificat expiré, nom d’hôte discordant) et c’est sur lui qu’il faut agir. Le préfixe est aussi un filtre pratique pour les journaux : le rechercher avec grep sépare les échecs de confiance TLS des erreurs applicatives, et c’est précisément pour cela que cet enveloppement a été ajouté.
Pourquoi cela se produit
Toutes les causes d’autorité inconnue
fréquenteCertificats intermédiaires manquants, AC privées, conteneurs dépourvus de certificats d’AC : tout ce qui produit « x509: certificate signed by unknown authority » apparaît désormais avec ce préfixe lorsque l’erreur survient pendant l’établissement d’une connexion TLS (dial) plutôt que lors d’un appel explicite à Verify.
Points de terminaison de développement ou auto-signés appelés par des clients configurés par défaut
fréquentehttp.Get vers un serveur local doté d’un certificat auto-signé (httptest.NewTLSServer depuis un autre processus, ingress minikube, proxy de développement) échoue ici, sauf si l’AC du serveur est fournie au client.
Le suffixe diffère : lisez-le
occasionnelle« ...: x509: certificate has expired » et « ...: x509: certificate is valid for X, not Y » sont des problèmes différents qui portent le même préfixe ; la correction dépend du suffixe, pas de la couche TLS.
Comment corriger l’erreur
- 1.
Fournir au client les bonnes ancres de confiance
Même remède que pour l’erreur x509 seule : un pool de racines contenant l’AC émettrice, configuré sur le transport réellement utilisé pour la connexion.
go pool := x509.NewCertPool() caPEM, _ := os.ReadFile("ca.pem") pool.AppendCertsFromPEM(caPEM) client := &http.Client{Transport: &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: pool}, }} resp, err := client.Get("https://internal.example:8443/healthz") - 2.
Examiner ce que présente le serveur
Examinez la chaîne servie, ses émetteurs et sa validité avant de toucher au code client : la plupart des corrections relèvent finalement de la configuration de la chaîne côté serveur.
bash openssl s_client -connect internal.example:8443 -servername internal.example \ </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates - 3.
Garder la vérification active, même dans les tests
Les serveurs httptest vous fournissent un client préconfiguré ; utilisez-le au lieu de désactiver la vérification globalement.
go srv := httptest.NewTLSServer(handler) defer srv.Close() resp, err := srv.Client().Get(srv.URL) // trusts srv's cert, nothing else