XTLS/Xray-core · warning

unexpected server version: {version}

Error message

unexpected server version: {version}

What it means

Thrown by the Xray SOCKS5 client (ClientHandshake) when the first byte of the server's method-selection reply is not 0x05. Per RFC 1928 the SOCKS5 server must reply with version 5; anything else means the remote is not speaking SOCKS5 or is a broken/misbehaving server. Marked AtWarning because it usually indicates a configuration mistake, not a code bug.

Source

Thrown at proxy/socks/protocol.go:461

	if request.User != nil {
		authByte = byte(authPassword)
	}

	b := buf.New()
	defer b.Release()

	common.Must2(b.Write([]byte{socks5Version, 0x01, authByte}))
	if err := buf.WriteAllBytes(writer, b.Bytes(), nil); err != nil {
		return nil, err
	}

	b.Clear()
	if _, err := b.ReadFullFrom(reader, 2); err != nil {
		return nil, err
	}

	if b.Byte(0) != socks5Version {
		return nil, errors.New("unexpected server version: ", b.Byte(0)).AtWarning()
	}
	if b.Byte(1) != authByte {
		return nil, errors.New("auth method not supported.").AtWarning()
	}

	if authByte == authPassword {
		b.Clear()
		account := request.User.Account.(*Account)
		common.Must(b.WriteByte(0x01))
		common.Must(b.WriteByte(byte(len(account.Username))))
		common.Must2(b.WriteString(account.Username))
		common.Must(b.WriteByte(byte(len(account.Password))))
		common.Must2(b.WriteString(account.Password))
		if err := buf.WriteAllBytes(writer, b.Bytes(), nil); err != nil {
			return nil, err
		}

		b.Clear()

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Verify the outbound address/port actually runs SOCKS5 (test with curl --socks5 host:port).
  2. If the target is a different protocol, change the outbound protocolHandler accordingly (http, trojan, vless...).
  3. If SOCKS4 is required instead, set the outbound to version 4 if supported or front it with a SOCKS5 server.
  4. Check for captive portals / MITM middleboxes rewriting the first response bytes.

Example fix

// xray config: pointing at an HTTPS port by mistake
// before
{ "protocol": "socks", "settings": { "servers": [ { "address": "1.2.3.4", "port": 443 } ] } }

// after (SOCKS5 actually listens on 1080)
{ "protocol": "socks", "settings": { "servers": [ { "address": "1.2.3.4", "port": 1080 } ] } }
Defensive patterns

Strategy: validation

Validate before calling

// smoke-test the endpoint before wiring it as a socks outbound
conn, err := net.DialTimeout("tcp", addr, 3*time.Second)
if err != nil { return err }
conn.Write([]byte{0x05, 0x01, 0x00})
reply := make([]byte, 2)
io.ReadFull(conn, reply)
if reply[0] != 0x05 { return fmt.Errorf("not a SOCKS5 server (version %d)", reply[0]) }

Try / catch

if err := client.Process(ctx, link, dialer); err != nil {
	if strings.Contains(err.Error(), "unexpected server version") {
		// endpoint is not SOCKS5; fix outbound address/port or protocol
	}
}

Prevention

When it happens

Trigger: Calling a SOCKS5 outbound where server.Destination points at a non-SOCKS5 service: an HTTP proxy port, an HTTPS port (first byte 0x16), a SOCKS4-only server, or a captive-portal HTML response.

Common situations: Outbound 'socks' address/port pointing at the wrong service; pointing at a Trojan/VLESS port by mistake; server behind a CDN or load balancer that answers TLS first; typo'd port in the outbound config.

Related errors


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