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
- Verify the server has a valid certificate chain configured and is sending it.
- Capture the Certificate message bytes to confirm emptiness.
- Ensure the connection is not accidentally in PSK mode where no cert is expected — but Go checks that separately.
- 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
- Verify the server has a valid certificate chain installed.
- Audit the network path for proxies that strip the chain.
- Use monitoring to alert on empty-chain errors across a fleet.
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: certificate used with invalid signature algorithm
- tls: server sent two HelloRetryRequest messages
- tls: server sent a cookie in a normal ServerHello
- tls: malformed key_share extension
- tls: server did not send a key share
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/1dc969baa34cca5d.
Report an issue: GitHub.