XTLS/Xray-core · error

invalid source IP address:

Error message

invalid source IP address: 

What it means

On macOS, FindProcess passes srcIP to netip.ParseAddr and it failed to parse (empty string, malformed IPv4/IPv6 text, or a value like 'localhost'). The source address must be a literal IP; hostnames and empty strings are rejected.

Source

Thrown at common/net/find_process_darwin.go:66

	darwinSocketLocalMatch
	darwinSocketExactMatch
)

func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (PID int, Name string, AbsolutePath string, err error) {
	isLocal, err := IsLocal(net.ParseIP(srcIP))
	if err != nil {
		return 0, "", "", errors.New("failed to determine if address is local: ", err)
	}
	if !isLocal {
		return 0, "", "", ErrNotLocal
	}
	if network != "tcp" && network != "udp" {
		panic("Unsupported network type for process lookup.")
	}

	srcAddr, err := netip.ParseAddr(srcIP)
	if err != nil {
		return 0, "", "", errors.New("invalid source IP address: ", srcIP)
	}
	srcAddr = srcAddr.Unmap()

	var dstAddr netip.Addr
	hasDstAddr := false
	if destIP != "" && destPort != 0 {
		dstAddr, err = netip.ParseAddr(destIP)
		if err != nil {
			return 0, "", "", errors.New("invalid destination IP address: ", destIP)
		}
		dstAddr = dstAddr.Unmap()
		hasDstAddr = true
	}

	processes, err := unix.SysctlKinfoProcSlice("kern.proc.all")
	if err != nil {
		return 0, "", "", errors.New("failed to list processes").Base(err)
	}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Pass the IP extracted from the connection: host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) and verify net.ParseIP(host) != nil.
  2. Skip the call when the source address is missing or not an IP literal.
  3. Trim whitespace/brackets from IPv6 literals before parsing.
  4. Add a unit check that formats srcIP with netip.Addr.String() at the call site.

Example fix

// before
pid, name, path, err := net.FindProcess("tcp", srcHost, srcPort, dstHost, dstPort) // srcHost may be "localhost"
// after
srcIP := net.ParseIP(srcHost)
if srcIP == nil {
    return fmt.Errorf("invalid source IP %q", srcHost)
}
pid, name, path, err := net.FindProcess("tcp", srcIP.String(), srcPort, dstIP.String(), dstPort)
Defensive patterns

Strategy: validation

Validate before calling

func validSourceIP(s string) bool { return net.ParseIP(s) != nil }

if !validSourceIP(srcIP) {
    return errors.New("invalid srcIP, cannot do process lookup")
}

Type guard

func isParseableIP(s string) bool {
    if s == "" { return false }
    if _, err := netip.ParseAddr(s); err != nil { return false }
    return true
}

Try / catch

pid, name, path, err := net.FindProcess(network, srcIP, srcPort, destIP, destPort)
if err != nil && strings.Contains(err.Error(), "invalid source IP address") {
    // caller bug: fix address extraction, do not retry with the same value
    log.Error("process lookup called with bad srcIP %q", srcIP)
}

Prevention

When it happens

Trigger: Calling FindProcess with srcIP="", srcIP containing a zone/hostname, or an address string with whitespace; also when a caller forwards the host part of an address pair instead of the IP.

Common situations: Custom callers extracting the source incorrectly from net.Conn (using addr.String() of a hostname-based Addr, or an uninitialized variable), or tests invoking FindProcess with placeholder strings.

Related errors


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