Zum Inhalt springen
ecdsa.com
Go crypto/tlsGo

Fehlermeldung

tls: first record does not look like a TLS handshake

gRPC, Datenbanktreiber und andere Bibliotheken verpacken den Fehler in eigene Meldungen, suche in den Logs also nach dem Kerntext. Bei HTTP-Antworten meldet net/http stattdessen „http: server gave HTTP response to HTTPS client“.

Go crypto/tls — the peer's first bytes are not a TLS record (tls.Dial, gRPC, database drivers, http.Client)

Was der Fehler bedeutet

Der TLS-Client von Go hat ein ClientHello gesendet, und der erste Record, den er zurückbekommen hat, hat nicht die Struktur eines TLS-Handshake-Records, deshalb gibt er sofort auf. Die Gegenseite spricht auf diesem Port etwas anderes: einfaches HTTP (wenn Go es nicht als solches erkennt), ein gRPC-Server im Klartext, die Begrüßung eines Datenbank- oder Mailprotokolls. Den umgekehrten Fall – ein Client, der Klartext an einen TLS-Port sendet – protokollieren Go-Server anders.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Prüfen, was der Port spricht

    Ein TLS-Handshake mit openssl oder ein kurzer Blick auf das Banner zeigt, ob der Port überhaupt TLS spricht.

    bash
    # Does the port speak TLS?
    openssl s_client -connect api.example.com:8080 -servername api.example.com -brief </dev/null
    timeout 3 nc api.example.com 8080 </dev/null | head -1     # a text banner = plain protocol
  2. 2.

    gRPC: die Credentials verwenden, die der Server erwartet

    TLS-Credentials für TLS-Server; unsichere Credentials nur für Klartext-Server in vertrauenswürdigen Netzen.

    go
    // gRPC: match the server. Plaintext server -> insecure credentials (only on trusted networks);
    // TLS server -> TLS credentials.
    conn, err := grpc.NewClient("api.example.com:9090",
    	grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ServerName: "api.example.com"})))
  3. 3.

    STARTTLS verwenden, wo das Protokoll es verlangt

    StartTLS aus net/smtp (und die Entsprechungen in Datenbanktreibern, etwa sslmode bei PostgreSQL) stellen die bestehende Verbindung in-band auf TLS um.

    go
    // SMTP on 587 starts in plain text: use STARTTLS, not tls.Dial
    c, err := smtp.Dial("mail.example.com:587")
    if err == nil {
    	err = c.StartTLS(&tls.Config{ServerName: "mail.example.com"})
    }

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen