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
- Pass the IP extracted from the connection: host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) and verify net.ParseIP(host) != nil.
- Skip the call when the source address is missing or not an IP literal.
- Trim whitespace/brackets from IPv6 literals before parsing.
- 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
- Extract the host with net.SplitHostPort from conn.RemoteAddr().
- Reject hostnames early — FindProcess wants IP literals only.
- Unit-test call sites with both IPv4 and IPv6 literals.
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
- invalid destination IP address:
- failed to determine if address is local:
- failed to parse user
- bridge tag is empty
- bridge domain is empty
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/6716dfed6ef645c2.
Report an issue: GitHub.