XTLS/Xray-core · error

TCP bind is not supported.

Error message

TCP bind is not supported.

What it means

Thrown in handshake5 (proxy/socks/protocol.go:179) when the SOCKS5 command byte is 0x02 (BIND). The server answers statusCmdNotSupport: Xray's SOCKS inbound deliberately implements only CONNECT and UDP ASSOCIATE; inbound BIND (accepting a reverse connection) is not supported.

Source

Thrown at proxy/socks/protocol.go:179

	}

	request := new(protocol.RequestHeader)
	if username != "" {
		request.User = &protocol.MemoryUser{Email: username}
	}
	switch cmd {
	case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:
		// We don't have a solution for Tor case now. Simply treat it as connect command.
		request.Command = protocol.RequestCommandTCP
	case cmdUDPAssociate:
		if !s.config.UdpEnabled {
			writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
			return nil, nil, errors.New("UDP is not enabled.")
		}
		request.Command = protocol.RequestCommandUDP
	case cmdTCPBind:
		writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
		return nil, nil, errors.New("TCP bind is not supported.")
	default:
		writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))
		return nil, nil, errors.New("unknown command ", cmd)
	}

	request.Version = socks5Version

	addr, port, err := addrParser.ReadAddressPort(nil, reader)
	if err != nil {
		return nil, nil, errors.New("failed to read address").Base(err)
	}
	request.Address = addr
	request.Port = port

	responseAddress := s.address
	responsePort := s.port
	var tempUDPConn *TempUDPConn
	//nolint:gocritic // Use if else chain for clarity

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Switch the application to passive/extended-passive mode (FTP PASV/EPSV), which only needs CONNECT.
  2. If a listener is truly required, use Xray's dedicated inbound types (dokodemo-door / port forwarding) instead of SOCKS BIND.
  3. Verify the command byte is not corrupted by bad client framing.

Example fix

# before: FTP active mode through SOCKS triggers BIND
curl --ftp-port - -x socks5h://127.0.0.1:1080 ftp://example.com/file

# after: passive mode only uses CONNECT
curl -P - -x socks5h://127.0.0.1:1080 ftp://example.com/file  # or just default passive mode
curl -x socks5h://127.0.0.1:1080 ftp://example.com/file
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: reject BIND up front instead of round-tripping
const sock5Bind = 0x02
if desiredCmd == sock5Bind {
    return fmt.Errorf("Xray SOCKS inbound does not support BIND; use passive mode or port forwarding")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "TCP bind is not supported") {
    return ErrUnsupportedOperation // switch app to passive mode
}

Prevention

When it happens

Trigger: A SOCKS5 client issues CMD=0x02, typically FTP active-mode data connections, some IRC DCC setups, or older P2P software.

Common situations: FTP clients configured for active mode through the proxy; applications assuming full RFC 1928 command coverage.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/5723fef4af8af962. Report an issue: GitHub.