{"record":{"id":"73511bb98eb4e719","repo":"golang/go","slug":"tls-invalid-signature-by-the-server-certificate","errorCode":null,"errorMessage":"tls: invalid signature by the server certificate: {err}","messagePattern":"tls: invalid signature by the server certificate: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":673,"sourceCode":"\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\n\t}\n\n\treturn nil\n}\n\nfunc (hs *clientHandshakeStateTLS13) readServerFinished() error {\n\tc := hs.c\n\n\t// finishedMsg is included in the transcript, but not until after we\n\t// check the client version, since the state before this message was\n\t// sent is used during verification.\n\tmsg, err := c.readHandshake(nil)\n\tif err != nil {","sourceCodeStart":655,"sourceCodeEnd":691,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L655-L691","documentation":"CertificateVerify signature verification failed: the server's signature over the transcript does not validate against the leaf certificate's public key. Go sends `decrypt_error`. This is the core authenticity check of the TLS 1.3 handshake; failure means the server does not hold the private key for the certificate it presented (MITM) or the handshake transcript was tampered with.","triggerScenarios":"verifyHandshakeSignature returns an error when checking certVerify.signature against c.peerCertificates[0].PublicKey over the signed transcript. Any TLS 1.3 handshake with a bad signature.","commonSituations":"Active MITM (the classic TLS attack signal), a misconfigured server using the wrong private key for its certificate, a certificate chain reissued without matching key, or transcript tampering by a proxy.","solutions":["Investigate as a potential MITM — do NOT bypass this check under any circumstances.","Verify the server's private key matches its certificate (re-issue/re-install the correct key pair).","Compare the certificate chain presented over a trusted network vs. the failing one.","Check for TLS-intercepting proxies, captive portals, or corporate firewalls that substitute certificates."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Signature verification failure may indicate MITM — never bypass.\nif err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"invalid signature by the server certificate\") {\n        securityLog.Printf(\"possible MITM against %s: %v\", addr, err)\n    }\n    return err\n}","preventionTips":["Never disable or weaken certificate verification to work around this error.","Verify the server's private key matches its certificate.","Use certificate pinning or a VerifyConnection callback for high-value endpoints.","Investigate any TLS-intercepting proxy in the network path."],"tags":["tls","tls13","handshake","certificate-verify","signature","authentication","security","mitm","network","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}