{"record":{"id":"81d3d695ec399971","repo":"golang/go","slug":"tls-failed-to-sign-ecdhe-parameters-s","errorCode":null,"errorMessage":"tls: failed to sign ECDHE parameters: %s","messagePattern":"tls: failed to sign ECDHE parameters: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/crypto/tls/key_agreement.go","lineNumber":217,"sourceCode":"\t\tsigType, sigHash, err := typeAndHashFromSignatureScheme(ka.signatureAlgorithm)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif sigHash == crypto.SHA1 {\n\t\t\ttlssha1.Value() // ensure godebug is initialized\n\t\t\ttlssha1.IncNonDefault()\n\t\t}\n\t\tsigned := slices.Concat(clientHello.random, hello.random, serverECDHEParams)\n\t\tif (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {\n\t\t\treturn nil, errors.New(\"tls: certificate cannot be used with the selected cipher suite\")\n\t\t}\n\t\tsignOpts := crypto.SignerOpts(sigHash)\n\t\tif sigType == signatureRSAPSS {\n\t\t\tsignOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}\n\t\t}\n\t\tsig, err = crypto.SignMessage(priv, config.rand(), signed, signOpts)\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"tls: failed to sign ECDHE parameters: \" + err.Error())\n\t\t}\n\t} else {\n\t\tsigType, sigHash, err := legacyTypeAndHashFromPublicKey(priv.Public())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsigned := hashForServerKeyExchange(sigType, clientHello.random, hello.random, serverECDHEParams)\n\t\tif (sigType == signaturePKCS1v15) != ka.isRSA {\n\t\t\treturn nil, errors.New(\"tls: certificate cannot be used with the selected cipher suite\")\n\t\t}\n\t\tsig, err = priv.Sign(config.rand(), signed, sigHash)\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"tls: failed to sign ECDHE parameters: \" + err.Error())\n\t\t}\n\t}\n\n\tskx := new(serverKeyExchangeMsg)\n\tsigAndHashLen := 0","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/key_agreement.go#L199-L235","documentation":"During TLS 1.0–1.2 ECDHE ServerKeyExchange parameter signing (modern path using crypto.SignMessage), the private key's Sign operation failed. The underlying error is appended via %s. This is a server-side signing failure, not a protocol error — the key could not produce a signature over the ECDHE parameters (client random + server random + server ECDHE params).","triggerScenarios":"Server calls crypto.SignMessage(priv, config.rand(), signed, signOpts) and it returns an error. Causes: HSM/PKCS#11 failure, corrupted key, unsupported sign options, RSA-PSS with wrong salt length, key revoked or locked.","commonSituations":"HSM or PKCS#11 token disconnected or session expired; corrupted key file; RSA key that doesn't support PSS; key in a hardware module requiring authentication that wasn't provided; a custom crypto.Signer implementation with a bug in its Sign method.","solutions":["Verify the private key file is valid: openssl rsa -check (RSA) or openssl ec -check (ECDSA).","If using an HSM/PKCS#11: ensure the token is connected, unlocked, and the session is active.","Test the key independently: write a small program that calls priv.Sign() outside of TLS.","If using a custom crypto.Signer, debug its Sign method implementation.","Ensure the key type matches the signing algorithm (RSA-PSS requires RSA key, ECDSA requires EC key)."],"exampleFix":"// Debug the signing key in isolation\n// before: untested custom signer in production\ncert := tls.Certificate{PrivateKey: customKey}\n// after: verify Sign works outside TLS first\nsig, err := customKey.Sign(rand.Reader, testHash, nil)\nif err != nil {\n    log.Fatal(\"key signing failed:\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Verify the key can sign before starting the server\nfunc testSigning(key crypto.Signer) error {\n    digest := make([]byte, 32)\n    opts := crypto.Hash(0) // vary based on key type\n    switch key.Public().(type) {\n    case *rsa.PublicKey:\n        opts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: crypto.SHA256}\n    }\n    _, err := key.Sign(rand.Reader, digest, opts)\n    return err\n}","typeGuard":null,"tryCatchPattern":"// Verify signing capability at startup\nif err := testSigning(cert.PrivateKey.(crypto.Signer)); err != nil {\n    log.Fatal(\"key cannot sign ECDHE parameters: \", err)\n}\n// Runtime:\nif err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"failed to sign ECDHE parameters\") {\n        log.Printf(\"ECDHE signing failure: %v\", err)\n    }\n}","preventionTips":["Test key signing at startup before accepting connections.","For HSM-backed keys, verify the signing path and session management.","Use standard key types loaded via tls.LoadX509KeyPair.","Monitor HSM health and connection stability."],"tags":["tls","tls12","ecdhe","signing","certificate","server-side"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}