golang/go · error
tls: certificate used with invalid signature algorithm
Error message
tls: certificate used with invalid signature algorithm
What it means
readServerCertificateVerify rejects a CertificateVerify message whose signature algorithm is not in the client's supported set for TLS 1.3 AND not valid for the certificate's public key type. RFC 8446 §4.2.3 constrains the algorithm; Go sends `illegal_parameter` on mismatch. Indicates a server signing with an algorithm the client did not offer or that does not match the cert key.
Source
Thrown at src/crypto/tls/handshake_client_tls13.go:660
// this message was sent is used.
msg, err = c.readHandshake(nil)
if err != nil {
return err
}
certVerify, ok := msg.(*certificateVerifyMsg)
if !ok {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certVerify, msg)
}
// See RFC 8446, Section 4.4.3.
// We don't use hs.hello.supportedSignatureAlgorithms because it might
// include PKCS#1 v1.5 and SHA-1 if the ClientHello also supported TLS 1.2.
if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms(c.vers, c.vers)) ||
!isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, signatureSchemesForPublicKey(c.vers, c.peerCertificates[0].PublicKey)) {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: certificate used with invalid signature algorithm")
}
sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
if err != nil {
return c.sendAlert(alertInternalError)
}
if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
return c.sendAlert(alertInternalError)
}
signed := signedMessage(serverSignatureContext, hs.transcript)
if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
sigHash, signed, certVerify.signature); err != nil {
c.sendAlert(alertDecryptError)
return errors.New("tls: invalid signature by the server certificate: " + err.Error())
}
c.peerSigAlg = certVerify.signatureAlgorithm
if err := transcriptMsg(certVerify, hs.transcript); err != nil {
return errView on GitHub (pinned to b6b368adc5)
Solutions
- Update the server certificate and signing logic to use TLS 1.3-approved algorithms (ECDSA-with-SHA256/384/512, RSASSA-PSS, Ed25519).
- Confirm the leaf certificate key type matches the signature algorithm the server emits.
- If you cannot change the server, restrict MaxVersion to tls.VersionTLS12 to fall back to TLS 1.2 rules.
- Capture the CertificateVerify and confirm the algorithm code against RFC 8446 §4.2.3.
Example fix
// before: client defaults to TLS 1.3, which rejects the server's legacy sig alg
cfg := &tls.Config{}
// after: cap at TLS 1.2 if the server cannot be upgraded (temporary workaround)
cfg := &tls.Config{MaxVersion: tls.VersionTLS12} Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: if you know the server is TLS 1.2-era, cap MaxVersion so TLS 1.3 sig rules do not apply.
if serverLegacySignatures {
cfg.MaxVersion = tls.VersionTLS12
} Try / catch
if err := conn.Handshake(); err != nil {
if strings.Contains(err.Error(), "invalid signature algorithm") {
// server is using a TLS-1.3-forbidden algorithm; upgrade server or cap at TLS 1.2
cfg.MaxVersion = tls.VersionTLS12
return retryHandshake(addr, cfg)
}
} Prevention
- Upgrade server certificates and signing logic to TLS 1.3-approved algorithms.
- Match certificate key type to the signature algorithm the server emits.
- Pin MaxVersion = tls.VersionTLS12 only as a temporary workaround for legacy servers.
When it happens
Trigger: certVerify.signatureAlgorithm is not in supportedSignatureAlgorithms(c.vers, c.vers) OR not in signatureSchemesForPublicKey of the leaf cert. Reached during CertificateVerify processing.
Common situations: Server using an older signature algorithm (e.g., PKCS#1 v1.5, SHA-1) that TLS 1.3 forbids, a cert/key-type mismatch on the server (e.g., DSA cert), or a server that ignores the client's signature_algorithms extension. Browser/standard clients reject these too.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: invalid signature by the server certificate: {err}
- tls: received empty certificates message
- tls: server sent two HelloRetryRequest messages
- tls: server sent a cookie in a normal ServerHello
- tls: malformed key_share extension
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/59404a95a3b72caa.
Report an issue: GitHub.