{"record":{"id":"5388eb288dd2b379","repo":"ginuerzh/gost","slug":"bind-read-reply-v","errorCode":null,"errorMessage":"bind: read reply %v","messagePattern":"bind: read reply (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"socks.go","lineNumber":1998,"sourceCode":"\tnet.Conn\n\thandshaked   bool\n\thandshakeMux sync.Mutex\n}\n\n// Handshake waits for a peer to connect to the bind port.\nfunc (c *socks5BindConn) Handshake() (err error) {\n\tc.handshakeMux.Lock()\n\tdefer c.handshakeMux.Unlock()\n\n\tif c.handshaked {\n\t\treturn nil\n\t}\n\n\tc.handshaked = true\n\n\trep, err := gosocks5.ReadReply(c.Conn)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"bind: read reply %v\", err)\n\t}\n\tif rep.Rep != gosocks5.Succeeded {\n\t\treturn fmt.Errorf(\"bind: peer connect failure\")\n\t}\n\tc.raddr, err = net.ResolveTCPAddr(\"tcp\", rep.Addr.String())\n\treturn\n}\n\nfunc (c *socks5BindConn) Read(b []byte) (n int, err error) {\n\tif err = c.Handshake(); err != nil {\n\t\treturn\n\t}\n\treturn c.Conn.Read(b)\n}\n\nfunc (c *socks5BindConn) Write(b []byte) (n int, err error) {\n\tif err = c.Handshake(); err != nil {\n\t\treturn","sourceCodeStart":1980,"sourceCodeEnd":2016,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/socks.go#L1980-L2016","documentation":"This error is returned by the SOCKS5 BIND client (socks5BindConn) when gosocks5.ReadReply fails while waiting for the server's second BIND reply (the reply sent when the peer finally connects back to the server's bind port). The wrapped %v is the underlying read/parse/transport error, so the message shows why the reply could not be read (connection reset, EOF, timeout, malformed reply).","triggerScenarios":"Calling Connect on a SOCKS5 BIND dialer and the control connection drops or times out while blocked waiting for gosocks5.ReadReply to return the second reply (after the first reply confirmed the bind address).","commonSituations":"The remote peer never connects back within the proxy's timeout; a NAT/firewall kills the idle control connection; the proxy server crashes or closes the connection mid-BIND handshake.","solutions":["Inspect the wrapped error (%v) to identify the root cause (EOF, reset, timeout) and check proxy server logs","Verify network paths (NAT, firewalls) keep the control connection alive long enough for the peer to connect back","Increase client timeout / keepalive settings if applicable","Retry the BIND operation, or switch to CONNECT-based proxying if reverse connections are not required"],"exampleFix":"// before\nrep, err := gosocks5.ReadReply(c.Conn)\nif err != nil {\n    return fmt.Errorf(\"bind: read reply %v\", err)\n}\n// after: surface the underlying cause distinctly\nrep, err := gosocks5.ReadReply(c.Conn)\nif err != nil {\n    return fmt.Errorf(\"bind: read reply: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// before BIND, verify proxy reachability\nconn, err := net.DialTimeout(\"tcp\", proxyAddr, 5*time.Second)\nif err != nil { return fmt.Errorf(\"proxy unreachable: %w\", err) }","typeGuard":null,"tryCatchPattern":"for attempt := 0; attempt < 3; attempt++ {\n    c, err := dialer.Bind(ctx, addr)\n    if err != nil {\n        if strings.Contains(err.Error(), \"bind: read reply\") { time.Sleep(backoff); continue }\n        return err\n    }\n    break\n}","preventionTips":["Pre-check proxy connectivity before BIND","Keep control connection alive; avoid long idle periods","Log the wrapped underlying error for diagnosis","Prefer CONNECT when peer-reverse connection is not strictly needed"],"tags":["socks5","bind","network","timeout"],"backgroundTag":"socks5-bind-read-failure","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}