{"record":{"id":"7dd7b6bad5544079","repo":"golang/go","slug":"tls-failed-to-sign-handshake-s","errorCode":null,"errorMessage":"tls: failed to sign handshake: %s","messagePattern":"tls: failed to sign handshake: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/crypto/tls/handshake_server_tls13.go","lineNumber":882,"sourceCode":"\tif err != nil {\n\t\treturn c.sendAlert(alertInternalError)\n\t}\n\n\tsigned := signedMessage(serverSignatureContext, hs.transcript)\n\tsignOpts := crypto.SignerOpts(sigHash)\n\tif sigType == signatureRSAPSS {\n\t\tsignOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}\n\t}\n\tsig, err := crypto.SignMessage(hs.cert.PrivateKey.(crypto.Signer), c.config.rand(), signed, signOpts)\n\tif err != nil {\n\t\tpublic := hs.cert.PrivateKey.(crypto.Signer).Public()\n\t\tif rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS &&\n\t\t\trsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS\n\t\t\tc.sendAlert(alertHandshakeFailure)\n\t\t} else {\n\t\t\tc.sendAlert(alertInternalError)\n\t\t}\n\t\treturn errors.New(\"tls: failed to sign handshake: \" + err.Error())\n\t}\n\tcertVerifyMsg.signature = sig\n\n\tif _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (hs *serverHandshakeStateTLS13) sendServerFinished() error {\n\tc := hs.c\n\n\tfinished := &finishedMsg{\n\t\tverifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),\n\t}\n\n\tif _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {","sourceCodeStart":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_server_tls13.go#L864-L900","documentation":"The TLS 1.3 server failed to sign the CertificateVerify message using its certificate's private key via crypto.SignMessage. The wrapping %s includes the underlying signing error. The server has a special case: if the key is RSA and too small for RSA-PSS (bit length < hash size * 2 + 2 bytes), it sends alertHandshakeFailure; otherwise it sends alertInternalError. This is a server-side configuration or hardware problem, not a client issue.","triggerScenarios":"The server's private key (hs.cert.PrivateKey typed as crypto.Signer) failed to produce a signature. Causes: RSA key too small for RSA-PSS with the negotiated hash; HSM/PKCS#11 token error; corrupted key material; hardware crypto accelerator failure; insufficient permissions on the key store.","commonSituations":"RSA certificate with a 1024-bit or smaller key used with TLS 1.3 (which requires RSA-PSS, needing larger keys); a PKCS#11 or HSM-backed key that is unreachable or has a session timeout; a cert/key pair loaded from an incorrect file path; key stored in a hardware module that requires a PIN that wasn't provided.","solutions":["If RSA: use a certificate with at least 2048-bit keys (RSA-PSS requires key_size_bytes >= hash_size*2 + 2).","Verify the private key file is valid and not corrupted (openssl rsa -check).","If using an HSM/PKCS#11: ensure the token is connected, the session is valid, and credentials are provided.","Switch to an ECDSA (P-256) certificate which avoids RSA-PSS minimum-size issues.","Check that the private key implements crypto.Signer correctly (custom key types must support Sign with the right options)."],"exampleFix":"// before: RSA 1024-bit certificate (too small for TLS 1.3 RSA-PSS)\ncert, _ := tls.LoadX509KeyPair(\"rsa1024.crt\", \"rsa1024.key\")\n// after: use at least RSA 2048-bit or switch to ECDSA P-256\ncert, _ := tls.LoadX509KeyPair(\"ecdsa_p256.crt\", \"ecdsa_p256.key\")","handlingStrategy":"validation","validationCode":"// Verify the private key can sign with the required algorithm before starting the server\nfunc verifySigningCapability(key crypto.Signer, sigAlg SignatureScheme) error {\n    _, _, err := typeAndHashFromSignatureScheme(sigAlg)\n    if err != nil {\n        return err\n    }\n    // For RSA, check minimum key size for PSS\n    if rsaKey, ok := key.Public().(*rsa.PublicKey); ok {\n        _, sigHash, _ := typeAndHashFromSignatureScheme(sigAlg)\n        if rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 {\n            return fmt.Errorf(\"RSA key too small (%d bits) for RSA-PSS with %v\", rsaKey.N.BitLen(), sigHash)\n        }\n    }\n    return nil\n}","typeGuard":"// Ensure private key implements crypto.Signer\nfunc isSigner(key any) bool {\n    _, ok := key.(crypto.Signer)\n    return ok\n}","tryCatchPattern":"// Server-side: check at startup\nerr := verifySigningCapability(cert.PrivateKey.(crypto.Signer), preferredSigAlg)\nif err != nil {\n    log.Fatal(\"server certificate cannot sign handshake: \", err)\n}\n// Runtime: handle Handshake() error\nif err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"failed to sign handshake\") {\n        log.Printf(\"signing failure during handshake: %v\", err)\n    }\n}","preventionTips":["Use RSA keys of at least 2048 bits to ensure compatibility with RSA-PSS in TLS 1.3.","Validate certificate/key pairs at server startup before accepting connections.","For HSM-backed keys, verify the signing path works before production.","Prefer ECDSA P-256 certificates which have no minimum-size issue."],"tags":["tls","tls13","handshake","signing","certificate","rsa","server-side"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}