XTLS/Xray-core · error

failed to read address

Error message

failed to read address

What it means

Thrown in handshake5 (proxy/socks/protocol.go:189) when addrParser.ReadAddressPort fails to parse the destination field of the SOCKS5 request: ATYP (IPv4/IPv6/domain) plus address and port. Malformed address type bytes, truncated addresses, or a dropped connection produce it.

Source

Thrown at proxy/socks/protocol.go:189

	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
			responseAddress = s.config.Address.AsAddress()
		} else {
			// Use conn.LocalAddr() IP as remote address in the response by default
			responseAddress = s.localAddress
		}
		udpHub, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{IP: responseAddress.IP(), Port: 0}, nil)
		if err != nil {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Encode the request per RFC 1928: ATYP 0x01 + 4-byte IP + 2-byte port, or ATYP 0x03 + 1-byte len + domain + 2-byte port, or ATYP 0x04 + 16-byte IPv6 + port.
  2. Check the base error: EOF/reset means transport loss; a parse error means framing is wrong.
  3. Test with curl --socks5-hostname to confirm the server side is healthy, then fix the custom client.

Example fix

// before: domain length byte wrong
conn.Write([]byte{0x05, 0x01, 0x00, 0x03, 0x0F, 'e','x','a','m','p','l','e','.','c','o','m', 0x00, 0x50})

// after: len=11 ("example.com") + port 80
conn.Write([]byte{0x05, 0x01, 0x00, 0x03, 0x0B, 'e','x','a','m','p','l','e','.','c','o','m', 0x00, 0x50})
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: encode the address field per RFC 1928 before writing
func socks5Addr(addr string, port uint16) ([]byte, error) {
    if ip := net.ParseIP(addr); ip != nil {
        if v4 := ip.To4(); v4 != nil {
            return append([]byte{0x01}, append(v4, byte(port>>8), byte(port))...), nil
        }
        b := append([]byte{0x04}, ip.To16()...)
        return append(b, byte(port>>8), byte(port)), nil
    }
    if len(addr) > 255 {
        return nil, fmt.Errorf("domain too long")
    }
    b := []byte{0x03, byte(len(addr))}
    b = append(b, addr...)
    return append(b, byte(port>>8), byte(port)), nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to read address") {
    return fmt.Errorf("malformed SOCKS5 destination: %w", err)
}

Prevention

When it happens

Trigger: Client sends an invalid ATYP (not 0x01/0x03/0x04); domain length prefix larger than the bytes actually sent; connection reset mid-request; stream desync after a bad auth exchange.

Common situations: Hand-rolled SOCKS5 encoders with wrong ATYP or length handling; proxies chaining protocols incorrectly; intermittent disconnects during handshake; clients sending Unicode domains with wrong length bytes.

Related errors


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