golang/go · error
tls: client certificate used with invalid signature algorith
Error message
tls: client certificate used with invalid signature algorithm
What it means
During mutual TLS (mTLS) client certificate verification, the client's CertificateVerify message specified a signature algorithm that the server doesn't support. The check uses two filters: (1) the algorithm must be in the server's supportedSignatureAlgorithms list for the negotiated version, and (2) it must be compatible with the client certificate's public key type via signatureSchemesForPublicKey. Additionally, PKCS#1 v1.5 and SHA-1 are explicitly rejected afterward. This is defined in RFC 8446 Section 4.4.3.
Source
Thrown at src/crypto/tls/handshake_server_tls13.go:1091
// 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 certReq.supportedSignatureAlgorithms because it would
// require keeping the certificateRequestMsgTLS13 around in the hs.
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: client 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(clientSignatureContext, 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 client certificate: " + err.Error())
}
c.peerSigAlg = certVerify.signatureAlgorithm
if err := transcriptMsg(certVerify, hs.transcript); err != nil {
return errView on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the client cert's signature algorithm matches its public key type (RSA key uses RSA-PSS, ECDSA key uses ECDSA, Ed25519 uses ed25519).
- Verify the client TLS library sends signature algorithms from the server's CertificateRequest supported_signature_algorithms list.
- Regenerate client certificate if its key type is incompatible with the negotiated algorithms.
- Update the client TLS library to one that correctly implements RFC 8446 §4.4.3 signature algorithm selection.
Example fix
// Ensure client cert key type matches signature algorithm // before: RSA cert but client sends ed25519 sig alg // after: client cert uses ECDSA P-256, sends ecdsa_secp256r1_sha256 // // Generate proper client cert: // openssl ecparam -genkey -name prime256v1 -out client.key // openssl req -new -x509 -key client.key -out client.crt
Defensive patterns
Strategy: validation
Validate before calling
// Client-side: verify signature algorithm is compatible with cert key type
func validateCertSigAlg(pubKey crypto.PublicKey, sigAlg SignatureScheme) error {
schemes := signatureSchemesForPublicKey(tls.VersionTLS13, pubKey)
for _, s := range schemes {
if s == sigAlg {
return nil
}
}
return fmt.Errorf("signature algorithm %v not compatible with public key type", sigAlg)
} Try / catch
// Server-side: handle during client cert verification
if err := conn.Handshake(); err != nil {
if strings.Contains(err.Error(), "invalid signature algorithm") {
log.Printf("client cert used unsupported signature algorithm: %v", err)
}
} Prevention
- Ensure client certificate key type matches the signature algorithms it uses.
- Configure the server's ClientAuth and acceptable signature algorithms consistently.
- Test mTLS with certificates that use standard key types (RSA-PSS, ECDSA, Ed25519).
When it happens
Trigger: Server requested client certificates (mTLS). Client sent a CertificateVerify with a signature algorithm not in the server's supported list, or one incompatible with the client cert's key type. For example: client uses an Ed25519 cert but claims ecdsa_secp256r1_sha256; or client uses a legacy algorithm the server no longer accepts.
Common situations: Client cert key type (e.g. Ed25519, RSA-PSS) doesn't match the claimed signature algorithm; client library forces a deprecated algorithm (SHA-1 or PKCS#1 v1.5); version mismatch between client and server signature algorithm policies; client cert generated with an unusual key type the server's signatureSchemesForPublicKey doesn't recognize.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: invalid signature by the client certificate: %s
- tls: client sent encrypted_client_hello extension with unsup
- tls: client sent encrypted_client_hello extension but did no
- tls: client certificate used with invalid signature algorith
- tls: client didn't provide a certificate
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/26a4f90a79836919.
Report an issue: GitHub.