Zum Inhalt springen
ecdsa.com
Go crypto/tls (Go ≥ 1.20)Go

Fehlermeldung

tls: failed to verify certificate: x509: certificate signed by unknown authority

Go crypto/tls (Go ≥ 1.20) — wrapping x509 verification errors

Was der Fehler bedeutet

Seit Go 1.20 verpacken fehlgeschlagene TLS-Handshakes den zugrunde liegenden x509-Fehler mit dem Präfix „tls: failed to verify certificate:“, sodass Logs sowohl die Ebene (TLS-Handshake) als auch die eigentliche Ursache zeigen (der Aufbau der Kette ist fehlgeschlagen). Das Suffix variiert – unbekannte Zertifizierungsstelle, abgelaufen, nicht passender Hostname – und ist der Teil, an dem du ansetzen musst. Das Präfix taugt außerdem als Log-Filter: Ein grep danach trennt TLS-Vertrauensfehler von Fehlern auf Anwendungsebene – genau dafür wurde das Verpacken eingeführt.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Dem Client die richtigen Vertrauensanker geben

    Dieselbe Abhilfe wie beim x509-Fehler ohne Präfix: ein Root-Pool mit der ausstellenden CA, gesetzt auf dem Transport, der für den Verbindungsaufbau tatsächlich verwendet wird.

    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. 2.

    Untersuchen, was der Server vorlegt

    Sieh dir die ausgelieferte Kette, ihre Aussteller und ihre Gültigkeit an, bevor du Client-Code anfasst – die meisten Korrekturen stellen sich als serverseitige Konfiguration der Kette heraus.

    bash
    openssl s_client -connect internal.example:8443 -servername internal.example \
      </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
  3. 3.

    Prüfung eingeschaltet lassen, auch in Tests

    httptest-Server liefern dir einen vorkonfigurierten Client; verwende ihn, statt die Prüfung global abzuschalten.

    go
    srv := httptest.NewTLSServer(handler)
    defer srv.Close()
    resp, err := srv.Client().Get(srv.URL)   // trusts srv's cert, nothing else

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen