{"record":{"id":"1dc969baa34cca5d","repo":"golang/go","slug":"tls-received-empty-certificates-message","errorCode":null,"errorMessage":"tls: received empty certificates message","messagePattern":"tls: received empty certificates message","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":630,"sourceCode":"\n\tcertReq, ok := msg.(*certificateRequestMsgTLS13)\n\tif ok {\n\t\ths.certReq = certReq\n\n\t\tmsg, err = c.readHandshake(hs.transcript)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tcertMsg, ok := msg.(*certificateMsgTLS13)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(certMsg, msg)\n\t}\n\tif len(certMsg.certificate.Certificate) == 0 {\n\t\tc.sendAlert(alertDecodeError)\n\t\treturn errors.New(\"tls: received empty certificates message\")\n\t}\n\n\tc.scts = certMsg.certificate.SignedCertificateTimestamps\n\tc.ocspResponse = certMsg.certificate.OCSPStaple\n\n\tif err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {\n\t\treturn err\n\t}\n\n\t// certificateVerifyMsg is included in the transcript, but not until\n\t// after we verify the handshake signature, since the state before\n\t// this message was sent is used.\n\tmsg, err = c.readHandshake(nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcertVerify, ok := msg.(*certificateVerifyMsg)","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L612-L648","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"empty certificates message\") {\n        log.Printf(\"server %s presented an empty certificate chain\", addr)\n    }\n    return err\n}","preventionTips":["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."],"tags":["tls","tls13","handshake","certificate","authentication","protocol-violation","network","go"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}