{"record":{"id":"6b7d7d3bcac5023f","repo":"fatedier/frp","slug":"create-encryption-stream-error-v","errorCode":null,"errorMessage":"create encryption stream error: %v","messagePattern":"create encryption stream error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/visitor/visitor.go","lineNumber":209,"sourceCode":"\t\tvisitorConn.Close()\n\t\treturn nil, fmt.Errorf(\"read newVisitorConnRespMsg error: %v\", err)\n\t}\n\t_ = visitorConn.SetReadDeadline(time.Time{})\n\n\tif newVisitorConnRespMsg.Error != \"\" {\n\t\tvisitorConn.Close()\n\t\treturn nil, fmt.Errorf(\"start new visitor connection error: %s\", newVisitorConnRespMsg.Error)\n\t}\n\treturn visitorConn, nil\n}\n\nfunc wrapVisitorConn(conn io.ReadWriteCloser, cfg *v1.VisitorBaseConfig) (io.ReadWriteCloser, func(), error) {\n\trwc := conn\n\tif cfg.Transport.UseEncryption {\n\t\tvar err error\n\t\trwc, err = libio.WithEncryption(rwc, []byte(cfg.SecretKey))\n\t\tif err != nil {\n\t\t\treturn nil, func() {}, fmt.Errorf(\"create encryption stream error: %v\", err)\n\t\t}\n\t}\n\trecycleFn := func() {}\n\tif cfg.Transport.UseCompression {\n\t\trwc, recycleFn = libio.WithCompressionFromPool(rwc)\n\t}\n\treturn rwc, recycleFn, nil\n}\n","sourceCodeStart":191,"sourceCodeEnd":218,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/client/visitor/visitor.go#L191-L218","documentation":"wrapVisitorConn failed while turning the raw visitor connection into an encrypted stream via libio.WithEncryption, which initializes an AES cipher by exchanging a salt and derived key over the connection. Failure here is almost always an I/O error writing the initialization data, because AES key derivation itself does not error for arbitrary secrets.","triggerScenarios":"libio.WithEncryption(rwc, []byte(cfg.SecretKey)) returns an error when writing the key-exchange preamble to the just-established connection fails; the peer closed between NewVisitorConnResp and this step.","commonSituations":"Server dropped the connection immediately after a successful visitor handshake; TLS/middlebox truncating the stream; transport.useEncryption enabled on the visitor while the target proxy owner has it disabled, so the peer closes on unexpected ciphertext framing.","solutions":["Ensure useEncryption matches on both sides: the visitor config and the stcp/xtcp proxy config must both set transport.useEncryption = true.","Check frps and the serving frpc logs for the peer closing the stream right at handshake time.","If this appears together with errors 120/121 intermittently, the same flaky network path is the root cause.","Retry the visitor connection; persistent recurrence points to the encryption flag mismatch."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure both endpoints agree on encryption before dialing\nvBase := visitorCfg.GetBaseConfig()\npBase := proxyCfg.GetBaseConfig()\nif vBase.Transport.UseEncryption != pBase.Transport.UseEncryption {\n    return fmt.Errorf(\"useEncryption mismatch between visitor and proxy\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mirror transport.useEncryption and useCompression between the stcp/xtcp proxy and its visitors","Template visitor configs from the proxy config so flags stay in sync"],"tags":["encryption","config","visitor","network"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}