{"record":{"id":"59404a95a3b72caa","repo":"golang/go","slug":"tls-certificate-used-with-invalid-signature-algor","errorCode":null,"errorMessage":"tls: certificate used with invalid signature algorithm","messagePattern":"tls: certificate used with invalid signature algorithm","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":660,"sourceCode":"\t// this message was sent is used.\n\tmsg, err = c.readHandshake(nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcertVerify, ok := msg.(*certificateVerifyMsg)\n\tif !ok {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn unexpectedMessageError(certVerify, msg)\n\t}\n\n\t// See RFC 8446, Section 4.4.3.\n\t// We don't use hs.hello.supportedSignatureAlgorithms because it might\n\t// include PKCS#1 v1.5 and SHA-1 if the ClientHello also supported TLS 1.2.\n\tif !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms(c.vers, c.vers)) ||\n\t\t!isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, signatureSchemesForPublicKey(c.vers, c.peerCertificates[0].PublicKey)) {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: certificate used with invalid signature algorithm\")\n\t}\n\tsigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)\n\tif err != nil {\n\t\treturn c.sendAlert(alertInternalError)\n\t}\n\tif sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {\n\t\treturn c.sendAlert(alertInternalError)\n\t}\n\tsigned := signedMessage(serverSignatureContext, hs.transcript)\n\tif err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,\n\t\tsigHash, signed, certVerify.signature); err != nil {\n\t\tc.sendAlert(alertDecryptError)\n\t\treturn errors.New(\"tls: invalid signature by the server certificate: \" + err.Error())\n\t}\n\tc.peerSigAlg = certVerify.signatureAlgorithm\n\n\tif err := transcriptMsg(certVerify, hs.transcript); err != nil {\n\t\treturn err","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L642-L678","documentation":"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.","triggerScenarios":"certVerify.signatureAlgorithm is not in supportedSignatureAlgorithms(c.vers, c.vers) OR not in signatureSchemesForPublicKey of the leaf cert. Reached during CertificateVerify processing.","commonSituations":"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.","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."],"exampleFix":"// before: client defaults to TLS 1.3, which rejects the server's legacy sig alg\ncfg := &tls.Config{}\n\n// after: cap at TLS 1.2 if the server cannot be upgraded (temporary workaround)\ncfg := &tls.Config{MaxVersion: tls.VersionTLS12}","handlingStrategy":"validation","validationCode":"// Pre-flight: if you know the server is TLS 1.2-era, cap MaxVersion so TLS 1.3 sig rules do not apply.\nif serverLegacySignatures {\n    cfg.MaxVersion = tls.VersionTLS12\n}","typeGuard":null,"tryCatchPattern":"if err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"invalid signature algorithm\") {\n        // server is using a TLS-1.3-forbidden algorithm; upgrade server or cap at TLS 1.2\n        cfg.MaxVersion = tls.VersionTLS12\n        return retryHandshake(addr, cfg)\n    }\n}","preventionTips":["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."],"tags":["tls","tls13","handshake","certificate-verify","signature","authentication","protocol-violation","network","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}