golang/go · error

tls: received unexpected CertificateStatus message

Error message

tls: received unexpected CertificateStatus message

What it means

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.

Solutions

  1. Disable or fix OCSP stapling on the server so status_request is consistently advertised.
  2. Remove any intermediary that injects CertificateStatus without negotiating it.
  3. Capture the handshake to confirm which side originates the spurious message.
Defensive patterns

Strategy: try-catch

Type guard

func isUnexpectedCertStatus(err error) bool {
    return err != nil && strings.Contains(err.Error(), "received unexpected CertificateStatus message")
}

Try / catch

if _, err := tls.Dial("tcp", addr, cfg); err != nil {
    if isUnexpectedCertStatus(err) {
        // Server bug; report to operator. Retrying will not help.
        reportServerDefect(addr, err)
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: Custom TLS stack with broken OCSP stapling logic; intermediate appliance injecting OCSP responses; rare for mainstream servers.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/crypto/tls/handshake_client.go:670

	}

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

	cs, ok := msg.(*certificateStatusMsg)
	if ok {
		// RFC4366 on Certificate Status Request:
		// The server MAY return a "certificate_status" message.

		if !hs.serverHello.ocspStapling {
			// If a server returns a "CertificateStatus" message, then the
			// server MUST have included an extension of type "status_request"
			// with empty "extension_data" in the extended server hello.

			c.sendAlert(alertUnexpectedMessage)
			return errors.New("tls: received unexpected CertificateStatus message")
		}

		c.ocspResponse = cs.response

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

	if c.handshakes == 0 {
		// If this is the first handshake on a connection, process and
		// (optionally) verify the server's certificates.
		if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
			return err
		}
	} else {
		// This is a renegotiation handshake. We require that the

View on GitHub (pinned to b6b368adc5)