{"record":{"id":"396bc8845e753c6f","repo":"golang/go","slug":"tls-received-unexpected-certificatestatus-message","errorCode":null,"errorMessage":"tls: received unexpected CertificateStatus message","messagePattern":"tls: received unexpected CertificateStatus message","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client.go","lineNumber":670,"sourceCode":"\t}\n\n\tmsg, err = c.readHandshake(&hs.finishedHash)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcs, ok := msg.(*certificateStatusMsg)\n\tif ok {\n\t\t// RFC4366 on Certificate Status Request:\n\t\t// The server MAY return a \"certificate_status\" message.\n\n\t\tif !hs.serverHello.ocspStapling {\n\t\t\t// If a server returns a \"CertificateStatus\" message, then the\n\t\t\t// server MUST have included an extension of type \"status_request\"\n\t\t\t// with empty \"extension_data\" in the extended server hello.\n\n\t\t\tc.sendAlert(alertUnexpectedMessage)\n\t\t\treturn errors.New(\"tls: received unexpected CertificateStatus message\")\n\t\t}\n\n\t\tc.ocspResponse = cs.response\n\n\t\tmsg, err = c.readHandshake(&hs.finishedHash)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif c.handshakes == 0 {\n\t\t// If this is the first handshake on a connection, process and\n\t\t// (optionally) verify the server's certificates.\n\t\tif err := c.verifyServerCertificate(certMsg.certificates); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// This is a renegotiation handshake. We require that the","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client.go#L652-L688","documentation":"Per RFC 4366, the server MAY send a CertificateStatus message only if it included the status_request extension with empty data in the ServerHello. The client tracks that via hs.serverHello.ocspStapling; if a CertificateStatus message arrives while that flag is false, the server is violating the protocol and the handshake fails with alertUnexpectedMessage.","triggerScenarios":"Misbehaving server or OCSP-stapling proxy sending CertificateStatus without having advertised status_request in its ServerHello; corrupted ServerHello where the status_request extension was lost.","commonSituations":"Custom TLS stack with broken OCSP stapling logic; intermediate appliance injecting OCSP responses; rare for mainstream servers.","solutions":["Disable or fix OCSP stapling on the server so status_request is consistently advertised.","Remove any intermediary that injects CertificateStatus without negotiating it.","Capture the handshake to confirm which side originates the spurious message."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isUnexpectedCertStatus(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"received unexpected CertificateStatus message\")\n}","tryCatchPattern":"if _, err := tls.Dial(\"tcp\", addr, cfg); err != nil {\n    if isUnexpectedCertStatus(err) {\n        // Server bug; report to operator. Retrying will not help.\n        reportServerDefect(addr, err)\n    }\n}","preventionTips":["Report server-side OCSP stapling defects to the operator.","Capture the handshake to confirm the originator of the message."],"tags":["tls","ocsp","handshake","protocol"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}