{"record":{"id":"f6ebcbe8d7741c17","repo":"golang/go","slug":"tls-failed-to-write-to-key-log","errorCode":null,"errorMessage":"tls: failed to write to key log: ","messagePattern":"tls: failed to write to key log: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client.go","lineNumber":787,"sourceCode":"\n\tif hs.serverHello.extendedMasterSecret {\n\t\tc.extMasterSecret = true\n\t\ths.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,\n\t\t\ths.finishedHash.Sum())\n\t} else {\n\t\tif fips140tls.Required() {\n\t\t\tif fips140ems.Value() != \"0\" {\n\t\t\t\tc.sendAlert(alertHandshakeFailure)\n\t\t\t\treturn errors.New(\"tls: FIPS 140-3 requires the use of Extended Master Secret\")\n\t\t\t}\n\t\t\tfips140ems.IncNonDefault()\n\t\t}\n\t\ths.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,\n\t\t\ths.hello.random, hs.serverHello.random)\n\t}\n\tif err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {\n\t\tc.sendAlert(alertInternalError)\n\t\treturn errors.New(\"tls: failed to write to key log: \" + err.Error())\n\t}\n\n\tif chainToSend != nil && len(chainToSend.Certificate) > 0 {\n\t\tcertVerify := &certificateVerifyMsg{}\n\n\t\tkey, ok := chainToSend.PrivateKey.(crypto.Signer)\n\t\tif !ok {\n\t\t\tc.sendAlert(alertInternalError)\n\t\t\treturn fmt.Errorf(\"tls: client certificate private key of type %T does not implement crypto.Signer\", chainToSend.PrivateKey)\n\t\t}\n\n\t\tif c.vers >= VersionTLS12 {\n\t\t\tsignatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)\n\t\t\tif err != nil {\n\t\t\t\tc.sendAlert(alertHandshakeFailure)\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tsigType, sigHash, err := typeAndHashFromSignatureScheme(signatureAlgorithm)","sourceCodeStart":769,"sourceCodeEnd":805,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client.go#L769-L805","documentation":"If Config.KeyLogWriter is non-nil, after deriving the master secret Go calls writeKeyLog(keyLogLabelTLS12, hello.random, masterSecret) which writes '<label> <client_random> <secret>\\n' to the writer. If Write returns an error, the handshake is aborted with alertInternalError and this message wrapping the underlying error.","triggerScenarios":"Config.KeyLogWriter points at a file on a full disk, a deleted file, a read-only filesystem, a closed pipe, or a custom Writer whose Write returns an error.","commonSituations":"SSLKEYLOGFILE path on a read-only mount in containers; disk full during long packet captures; key log redirected to a pipe whose consumer exited; file permissions wrong.","solutions":["Point Config.KeyLogWriter at a writable path on a volume with adequate free space.","If logging is best-effort, wrap the writer so Write never returns an error (log the failure out-of-band instead of failing the handshake).","Set Config.KeyLogWriter to nil in production unless you actively need to debug."],"exampleFix":"// before: a writer whose error aborts the handshake\ncfg := &tls.Config{KeyLogWriter: f} // f may fail\n// after: swallow write errors so the handshake never breaks\ntype safeWriter struct{ w io.Writer }\nfunc (s safeWriter) Write(p []byte) (int, error) {\n    n, err := s.w.Write(p)\n    if err != nil { log.Printf(\"keylog write failed: %v\", err); return len(p), nil }\n    return n, nil\n}\ncfg := &tls.Config{KeyLogWriter: safeWriter{w: f}}","handlingStrategy":"validation","validationCode":"// Wrap the key log writer so it never fails the handshake.\ntype safeKeyLogWriter struct{ w io.Writer }\nfunc (s safeKeyLogWriter) Write(p []byte) (int, error) {\n    n, err := s.w.Write(p)\n    if err != nil { log.Printf(\"keylog write failed: %v\", err); return len(p), nil }\n    return n, nil\n}\ncfg.KeyLogWriter = safeKeyLogWriter{w: f}","typeGuard":"func isKeyLogWriteError(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"tls: failed to write to key log\")\n}","tryCatchPattern":"if _, err := tls.Dial(\"tcp\", addr, cfg); err != nil {\n    if isKeyLogWriteError(err) {\n        // The key log destination is broken; drop logging and retry.\n        cfg.KeyLogWriter = nil\n        _, err = tls.Dial(\"tcp\", addr, cfg)\n    }\n}","preventionTips":["Do not set Config.KeyLogWriter in production.","Ensure the log path is on writable, non-full storage.","Wrap the writer to swallow errors if logging is best-effort."],"tags":["tls","debugging","keylog","config"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}