golang/go · error
tls: client certificate used with invalid signature algorith
Error message
tls: client certificate used with invalid signature algorithm
What it means
The client's CertificateVerify message used a signature algorithm that the server did not advertise in its CertificateRequest. TLS 1.2+ requires the client to pick from the server's supported_signature_algorithms list; picking outside it is illegal_parameter.
Source
Thrown at src/crypto/tls/handshake_server.go:781
// 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)
if !ok {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certVerify, msg)
}
var sigType uint8
var sigHash crypto.Hash
if c.vers >= VersionTLS12 {
if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: client certificate used with invalid signature algorithm")
}
sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
if err != nil {
return c.sendAlert(alertInternalError)
}
if sigHash == crypto.SHA1 {
tlssha1.Value() // ensure godebug is initialized
tlssha1.IncNonDefault()
}
if hs.finishedHash.buffer == nil {
c.sendAlert(alertInternalError)
return errors.New("tls: internal error: did not keep handshake transcript for TLS 1.2")
}
if err := verifyHandshakeSignature(sigType, pub, sigHash, hs.finishedHash.buffer, certVerify.signature); err != nil {
c.sendAlert(alertDecryptError)
return errors.New("tls: invalid signature by the client certificate: " + err.Error())
}
} else {View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the client signs CertificateVerify with one of the algorithms the server advertised in its CertificateRequest.
- On the server side, broaden supported signature algorithms if interoperability with the client is required.
- Update the client TLS stack — modern libraries pick from the server's list automatically.
- Verify the client certificate's key type supports the algorithm being requested.
Example fix
// Server: ensure the algorithm list matches what legitimate clients can use
cfg := &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
// Go selects supported algorithms automatically; do not over-restrict.
}
// Client: use a current TLS library — Go picks from server's list.
// Custom signing code must honor certReq.supportedSignatureAlgorithms. Defensive patterns
Strategy: validation
Validate before calling
// Client: pick a signature algorithm from the server's CertificateRequest // list. Go's standard machinery does this automatically. // For manual signers, intersect supported algorithms with the server list.
Try / catch
// Server: broaden supported algorithms if interoperability is required,
// or log which algorithm the client mis-used.
if err != nil && strings.Contains(err.Error(), "invalid signature algorithm") {
log.Warn("client used unadvertised signature algorithm",
"remote", conn.RemoteAddr())
} Prevention
- Use a current TLS library for the client — it honors the server's algorithm list.
- Do not hard-code SHA1 or other weak algorithms in custom signers.
- Keep the server's algorithm list broad enough for legitimate clients.
When it happens
Trigger: In the TLS 1.2 client-cert path, isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) returned false. The client signed with e.g. RSA-PKCS1-SHA1 when the server only offered SHA256+.
Common situations: A client library defaulting to a weak or legacy signature algorithm (SHA1, MD5) against a hardened server, mismatched signature algorithm support between client and server policy, or a misconfigured client cert whose key only supports certain algorithms.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: client does not support uncompressed connections
- tls: initial handshake had non-empty renegotiation extension
- tls: invalid signature by the client certificate: {err}
- tls: received new session ticket from a client
- tls: FIPS 140-3 requires the use of Extended Master Secret
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/9235beb96c779fa0.
Report an issue: GitHub.