{"record":{"id":"8fd8eecfc0075df6","repo":"snail007/goproxy","slug":"write-connection-data-err-s-retrying","errorCode":null,"errorMessage":"write connection data err: %s ,retrying...","messagePattern":"write connection data err: (.+?) ,retrying\\.\\.\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/tunnel_client.go","lineNumber":94,"sourceCode":"}\nfunc (s *TunnelClient) Clean() {\n\ts.StopService()\n}\nfunc (s *TunnelClient) GetInConn(typ uint8) (outConn net.Conn, err error) {\n\toutConn, err = s.GetConn()\n\tif err != nil {\n\t\terr = fmt.Errorf(\"connection err: %s\", err)\n\t\treturn\n\t}\n\tkeyBytes := []byte(*s.cfg.Key)\n\tkeyLength := uint16(len(keyBytes))\n\tpkg := new(bytes.Buffer)\n\tbinary.Write(pkg, binary.LittleEndian, typ)\n\tbinary.Write(pkg, binary.LittleEndian, keyLength)\n\tbinary.Write(pkg, binary.LittleEndian, keyBytes)\n\t_, err = outConn.Write(pkg.Bytes())\n\tif err != nil {\n\t\terr = fmt.Errorf(\"write connection data err: %s ,retrying...\", err)\n\t\tutils.CloseConn(&outConn)\n\t\treturn\n\t}\n\treturn\n}\nfunc (s *TunnelClient) GetConn() (conn net.Conn, err error) {\n\tvar _conn tls.Conn\n\t_conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)\n\tif err == nil {\n\t\tconn = net.Conn(&_conn)\n\t}\n\treturn\n}\nfunc (s *TunnelClient) ServeUDP() {\n\tvar inConn net.Conn\n\tvar err error\n\tfor {\n\t\tfor {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/snail007/goproxy/blob/e6d6a821db80e7f47ee6e981a144984e1d4ddb3d/services/tunnel_client.go#L76-L112","documentation":"After GetConn succeeds, GetInConn writes a handshake packet (type, key length, key) to the new connection. This error is thrown when that write fails; the connection is closed immediately so the caller can retry, as the message says.","triggerScenarios":"outConn.Write(pkg.Bytes()) fails after the connection was established — typically because the server closed the conn right after accept (auth/key rejected, TLS failure, server restarting) or the network dropped mid-write; GetInConn closes outConn and returns the wrapped error.","commonSituations":"Mismatched client key so the server drops the connection; server restarted between accept and read; intermediate proxy/firewall RSTs the connection; unstable mobile/VPN network dropping packets.","solutions":["Confirm the client key (cfg.Key) matches the server's key, since the server may drop conns on bad keys","Retry the operation — the code already closes the conn and the message indicates retrying; add backoff in your wrapper","Check server-side logs at the same timestamp for why the server closed the accepted connection","Stabilize the network path (keep-alives, TCP keepalive settings) if running over flaky links"],"exampleFix":"// before: fire-and-forget single attempt\nconn, err := client.GetInConn(typ)\n// after: retry with backoff\nvar conn net.Conn\nfor i := 0; i < 3; i++ {\n    conn, err = client.GetInConn(typ)\n    if err == nil { break }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}","handlingStrategy":"retry","validationCode":"// verify key length is sane and matches server expectation before writing\nif len(cfg.Key) == 0 || len(cfg.Key) > 65535 {\n    return errors.New(\"tunnel key must be non-empty and <64KB\")\n}","typeGuard":null,"tryCatchPattern":"conn, err := client.GetInConn(typ)\nif err != nil && strings.Contains(err.Error(), \"write connection data err\") {\n    time.Sleep(backoff) // conn already closed by lib; just retry\n    conn, err = client.GetInConn(typ)\n}","preventionTips":["Match the client key exactly with the server key config","Enable TCP keepalive and retry with exponential backoff on flaky links","Watch server logs for simultaneous close events to catch auth/version mismatch","Avoid restarting the server during active client handshakes; drain first"],"tags":["network","tunnel","write-failure","retry"],"backgroundTag":"connection-reset-by-peer","analyzedSha":"e6d6a821db80e7f47ee6e981a144984e1d4ddb3d","analyzedAt":"2026-09-03T15:32:42.750Z","contentChangedAt":"2026-09-03T15:32:42.750Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}