Message d’erreur
x509: certificate signed by unknown authority
Go crypto/x509 — returned by Certificate.Verify and TLS dials
Ce que cela signifie
Go a tenté de construire une chaîne allant du certificat du serveur à une racine à laquelle il fait confiance, et n’y est pas parvenu : aucun chemin n’aboutit à un certificat du pool de racines configuré. Le certificat peut être parfaitement valide ; Go n’a simplement aucune raison de faire confiance à son émetteur. C’est l’erreur TLS la plus fréquente dans les déploiements Go.
Pourquoi cela se produit
Le serveur n’envoie pas le certificat intermédiaire
fréquenteLes racines des magasins de confiance signent les certificats intermédiaires, qui signent à leur tour les certificats feuilles. Un serveur configuré avec le seul certificat feuille (cert.pem au lieu de fullchain.pem) empêche Go d’établir le lien feuille → racine. Les navigateurs masquent souvent le problème grâce aux certificats intermédiaires en cache ; Go, non.
AC interne ou privée absente du pool
fréquenteLes AC d’entreprise, les certificats auto-signés de développement et les certificats émis par un service mesh sont, par conception, inconnus du magasin du système. Ils doivent être indiqués explicitement au client.
Image de conteneur minimale sans certificats d’AC
fréquenteLes images scratch et slim ne contiennent pas /etc/ssl/certs. Chaque connexion TLS échoue alors avec cette erreur, aussi public et valide que soit le certificat de la cible.
Un proxy d’interception re-signe le trafic
occasionnelleLes équipements d’inspection TLS des entreprises remplacent les certificats par d’autres, signés par l’AC de l’entreprise. Les machines sur lesquelles cette AC n’est pas installée considèrent tous les sites externes comme non fiables.
Comment corriger l’erreur
- 1.
Ajouter l’AC au pool de racines du client
Complétez le pool du système plutôt que de le remplacer, pour que les sites publics continuent de fonctionner à côté de votre AC interne.
go roots, err := x509.SystemCertPool() if err != nil { roots = x509.NewCertPool() } pem, _ := os.ReadFile("internal-ca.pem") roots.AppendCertsFromPEM(pem) client := &http.Client{Transport: &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: roots}, }} - 2.
Corriger le serveur : servir la chaîne complète
Vérifiez ce que le serveur envoie réellement ; si un seul certificat apparaît, configurez le serveur avec le fichier de chaîne complète (par exemple le fullchain.pem de Let's Encrypt).
bash openssl s_client -connect api.example.com:443 -showcerts </dev/null \ | grep -c "BEGIN CERTIFICATE" # 1 = leaf only (broken), 2+ = chain present - 3.
Inclure les certificats d’AC dans l’image
Pour les images minimales, copiez-y un fichier de certificats d’AC au moment du build. Ne « résolvez » jamais le problème avec InsecureSkipVerify : cette option désactive entièrement la vérification.
docker FROM alpine AS certs RUN apk add --no-cache ca-certificates FROM scratch COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/