golang/go · error

tls: received empty certificates message

Error message

tls: received empty certificates message

What it means

readServerCertificate received a Certificate message (TLS 1.3) whose certificate chain is empty. RFC 8446 §4.4.2 requires at least one certificate unless PSK-only authentication is used. Go sends `decode_error`. Indicates a server that sent an empty chain while doing certificate authentication.

Source

Thrown at src/crypto/tls/handshake_client_tls13.go:630

	certReq, ok := msg.(*certificateRequestMsgTLS13)
	if ok {
		hs.certReq = certReq

		msg, err = c.readHandshake(hs.transcript)
		if err != nil {
			return err
		}
	}

	certMsg, ok := msg.(*certificateMsgTLS13)
	if !ok {
		c.sendAlert(alertUnexpectedMessage)
		return unexpectedMessageError(certMsg, msg)
	}
	if len(certMsg.certificate.Certificate) == 0 {
		c.sendAlert(alertDecodeError)
		return errors.New("tls: received empty certificates message")
	}

	c.scts = certMsg.certificate.SignedCertificateTimestamps
	c.ocspResponse = certMsg.certificate.OCSPStaple

	if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
		return err
	}

	// certificateVerifyMsg is included in the transcript, but not until
	// after we verify the handshake signature, since the state before
	// this message was sent is used.
	msg, err = c.readHandshake(nil)
	if err != nil {
		return err
	}

	certVerify, ok := msg.(*certificateVerifyMsg)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Verify the server has a valid certificate chain configured and is sending it.
  2. Capture the Certificate message bytes to confirm emptiness.
  3. Ensure the connection is not accidentally in PSK mode where no cert is expected — but Go checks that separately.
  4. Report to the server operator; client-side there is no workaround.
Defensive patterns

Strategy: try-catch

Try / catch

if err := conn.Handshake(); err != nil {
    if strings.Contains(err.Error(), "empty certificates message") {
        log.Printf("server %s presented an empty certificate chain", addr)
    }
    return err
}

Prevention

When it happens

Trigger: UsingPSK is false (so a certificate is expected) and certMsg.certificate.Certificate has length 0. Reached whenever a TLS 1.3 server omits its leaf certificate.

Common situations: Server misconfiguration (no certificate loaded), a proxy that strips the certificate chain, an anonymous-authentication server that is not using PSK, or a buggy server.

Understand the failure class

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/1dc969baa34cca5d. Report an issue: GitHub.