ginuerzh/gost · error

Bind on %s failure

Error message

Bind on %s failure

What it means

This error comes from the rtcp (relay/tunnel over SOCKS5 BIND) forwarding path. The client sent a SOCKS5 BIND request to the relay and the server replied with a non-Success REP code, meaning the remote side refused or failed to establish the BIND. The connection is aborted and no smux session is created.

Source

Thrown at forward.go:528

	conn, err = socks5Handshake(conn, userSocks5HandshakeOption(l.chain.LastNode().User))
	if err != nil {
		return nil, err
	}
	req := gosocks5.NewRequest(CmdMuxBind, toSocksAddr(l.addr))
	if err := req.Write(conn); err != nil {
		log.Log("[rtcp] SOCKS5 BIND request: ", err)
		return nil, err
	}

	rep, err := gosocks5.ReadReply(conn)
	if err != nil {
		log.Log("[rtcp] SOCKS5 BIND reply: ", err)
		return nil, err
	}
	if rep.Rep != gosocks5.Succeeded {
		log.Logf("[rtcp] bind on %s failure", l.addr)
		return nil, fmt.Errorf("Bind on %s failure", l.addr.String())
	}
	log.Logf("[rtcp] BIND ON %s OK", rep.Addr)

	// Upgrade connection to multiplex stream.
	session, err := smux.Server(conn, smux.DefaultConfig())
	if err != nil {
		return nil, err
	}
	l.session = &muxSession{
		conn:    conn,
		session: session,
	}

	return l.session, nil
}

func (l *tcpRemoteForwardListener) waitConnectSOCKS5(conn net.Conn) (net.Conn, error) {
	conn, err := socks5Handshake(conn, userSocks5HandshakeOption(l.chain.LastNode().User))

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Check relay server logs for the SOCKS5 BIND failure reason and fix the underlying cause (port in use, firewall, permission rules).
  2. Verify the relay node allows the bind action in its permissions config (e.g. permissions like connect,bind).
  3. Confirm the relay host is publicly reachable and the target bind port is not occupied.
  4. Retry after correcting the tunnel/relay configuration; the error is not transient-safe to blind-retry.

Example fix

// before: bind relay without bind permission
permissions: "connect"
// after
permissions: "connect,bind"
Defensive patterns

Strategy: retry

Validate before calling

// probe relay before opening tunnel
func relayReachable(addr string) bool {
    c, err := net.DialTimeout("tcp", addr, 5*time.Second)
    if err != nil { return false }
    c.Close(); return true
}

Try / catch

for i := 0; i < 3; i++ {
    s, err := getSession(conn)
    if err == nil { return s }
    if !strings.Contains(err.Error(), "Bind on") { return nil, err }
    time.Sleep(time.Duration(1<<i) * time.Second)
}
return nil, errors.New("bind kept failing")

Prevention

When it happens

Trigger: getSession calls the SOCKS5 connector with BIND; the gosocks5 reply (rep.Rep) is anything other than gosocks5.Succeeded — e.g. connection refused/blocked at the relay, port allocation failure, or auth/permission denial on the relay node.

Common situations: Remote port forwarding through a gost relay when the relay host cannot open the requested port; firewall on the relay blocking the listen; relay configured with permissions that exclude BIND; relay behind NAT unable to accept inbound connections.

Related errors


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/4070752f41406bdf. Report an issue: GitHub.