shadow1ng/fscan · warning

%s [socks5_unsupported_version]

Error message

%s [socks5_unsupported_version]

What it means

The client's SOCKS5 greeting declared a version other than 0x05 or advertised zero authentication methods, so the handshake is rejected. This library throws it because it only supports SOCKS5 (RFC 1928) with at least one method.

Source

Thrown at plugins/local/socks5proxy.go:169

		return
	}
	defer func() { _ = targetConn.Close() }()

	session.LogSuccess(i18n.GetText("socks5_connected"))

	// 双向数据转发
	p.relayData(clientConn, targetConn)
}

// handleSocks5Handshake 处理SOCKS5握手
func (p *Socks5ProxyPlugin) handleSocks5Handshake(conn net.Conn) error {
	header := make([]byte, 2)
	if _, err := io.ReadFull(conn, header); err != nil {
		return fmt.Errorf("%s: %w", i18n.GetText("socks5_handshake_read_failed"), err)
	}

	if header[0] != 0x05 || header[1] == 0 {
		return fmt.Errorf("%s", i18n.GetText("socks5_unsupported_version"))
	}
	methods := make([]byte, int(header[1]))
	if _, err := io.ReadFull(conn, methods); err != nil {
		return fmt.Errorf("%s: %w", i18n.GetText("socks5_handshake_read_failed"), err)
	}
	if !containsByte(methods, 0x00) {
		_, _ = conn.Write([]byte{0x05, 0xff})
		return fmt.Errorf("%s", i18n.GetText("socks5_unsupported_version"))
	}

	// 发送握手响应(无认证)
	response := []byte{0x05, 0x00} // 版本5,无认证
	if _, err := conn.Write(response); err != nil {
		return fmt.Errorf("%s: %w", i18n.GetText("socks5_handshake_write_failed"), err)
	}

	return nil
}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Reconfigure the client to use SOCKS5 (version 5) rather than SOCKS4/SOCKS4a.
  2. Ensure the client sends a valid greeting: [0x05, N] followed by N method bytes.
  3. If you control the client code, include 0x00 (no-auth) in the offered methods to match this server.
  4. Point the offending scanner/tool away from the SOCKS port.

Example fix

// before (client sending bad greeting)
conn.Write([]byte{0x04, 0x01}) // SOCKS4 — rejected
// after
conn.Write([]byte{0x05, 0x01, 0x00}) // SOCKS5, one method: no-auth
Defensive patterns

Strategy: validation

Validate before calling

// client-side: verify greeting bytes before sending
func greeting() []byte {
	b := []byte{0x05, 0x01, 0x00} // SOCKS5, 1 method: NO-AUTH
	if b[0] != 0x05 || b[1] == 0 || len(b) < int(2+b[1]) {
		panic("invalid socks5 greeting")
	}
	return b
}

Type guard

func isSocks5Greeting(b []byte) bool {
	return len(b) >= 2 && b[0] == 0x05 && b[1] > 0
}

Try / catch

if err := handleSocks5Handshake(conn); err != nil {
	if strings.Contains(err.Error(), "socks5_unsupported_version") {
		// log client address; likely SOCKS4 or malformed client
	}
}

Prevention

When it happens

Trigger: In handleSocks5Handshake, header[0] != 0x05 or header[1] == 0 after successfully reading the 2-byte header — e.g. a SOCKS4 client (version byte 0x04) or a malformed/empty method list.

Common situations: Client configured for SOCKS4/SOCKS4a instead of SOCKS5; hand-rolled client sending only [0x05] without a method count; fuzzers or protocol-mismatched tools hitting the port.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/9fa83c7b5ac94dea. Report an issue: GitHub.