XTLS/Xray-core · error

unknown command {cmd}

Error message

unknown command {cmd}

What it means

Thrown in handshake5 (proxy/socks/protocol.go:182) when the SOCKS5 command byte is not one of the implemented values: 0x01 (CONNECT), 0x02 handled separately as unsupported BIND, 0x03 (UDP ASSOCIATE), or the Tor extensions 0xF0/0xF1 (RESOLVE/RESOLVE_PTR, treated as CONNECT). Anything else gets statusCmdNotSupport and this error.

Source

Thrown at proxy/socks/protocol.go:182

	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
	if request.Command == protocol.RequestCommandUDP {
		if s.config.Address != nil {
			// Use configured IP as remote address in the response to UDP Associate

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Verify the client's request framing: VER 0x05, CMD 0x01/0x03, RSV 0x00, then the address.
  2. Confirm the connection is actually speaking SOCKS5 to this port (protocol mismatch produces random command bytes).
  3. Check that earlier negotiation steps (auth) consumed exactly the right number of bytes.
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: whitelist known commands before sending
var cmd byte = 0x01
switch op {
case "connect": cmd = 0x01
case "udp": cmd = 0x03
default: return fmt.Errorf("unsupported SOCKS5 operation %q", op)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unknown command") {
    return fmt.Errorf("client sent an invalid SOCKS5 command byte; check framing")
}

Prevention

When it happens

Trigger: Garbage command bytes from a malformed client, stream desynchronization after an earlier framing error, or a client using a non-standard command the server does not implement.

Common situations: Byte-offset bugs in custom clients; a previous protocol step consuming the wrong number of bytes so the CMD field lands on random data; non-SOCKS traffic (HTTP/TLS) hitting the port and being partially interpreted.

Related errors


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