XTLS/Xray-core · error
invalid destination IP address:
Error message
invalid destination IP address:
What it means
On macOS, FindProcess optionally parses destIP (when both destIP is non-empty and destPort is non-zero) with netip.ParseAddr, and it failed. Like error 178, the destination must be a bare IP literal — hostnames, empty ports with non-empty IPs are handled, but malformed IP text aborts the lookup.
Source
Thrown at common/net/find_process_darwin.go:75
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)
}
var bestPID int32
bestLevel := darwinSocketNoMatch
ambiguousBest := false
for _, process := range processes {
pid := process.Proc.P_pid
if pid <= 0 {
continueView on GitHub (pinned to 7d214f8b09)
Solutions
- Resolve hostnames to IPs before calling FindProcess, or omit both destIP and destPort (pass "" and 0) to skip exact-match narrowing.
- Validate with net.ParseIP(destIP) != nil at the call site and degrade gracefully (fall back to lookup without destination filter).
- Ensure IPv6 addresses are passed without surrounding brackets.
- Log the offending destIP value to catch formatting bugs quickly.
Example fix
// before
pid, name, path, err := net.FindProcess("tcp", srcIP, srcPort, "example.com", 443)
// after: resolve first, or omit destination narrowing
var dstIPStr string
if ip := net.ParseIP(dstHost); ip != nil {
dstIPStr = ip.String()
}
pid, name, path, err := net.FindProcess("tcp", srcIP, srcPort, dstIPStr, dstPort) Defensive patterns
Strategy: validation
Validate before calling
if destIP != "" && destPort != 0 {
if _, err := netip.ParseAddr(destIP); err != nil {
return errors.New("destIP is not an IP literal; pass empty dest to skip narrowing")
}
} Type guard
func isParseableDest(ip string, port uint16) bool {
if ip == "" || port == 0 { return true } // optional: absent is fine
_, err := netip.ParseAddr(ip)
return err == nil
} Try / catch
pid, name, path, err := net.FindProcess(network, srcIP, srcPort, destIP, destPort)
if err != nil && strings.Contains(err.Error(), "invalid destination IP address") {
// retry once without destination narrowing (destIP="", destPort=0)
pid, name, path, err = net.FindProcess(network, srcIP, srcPort, "", 0)
} Prevention
- Resolve domains to IPs before calling FindProcess, or omit the destination pair entirely.
- Strip brackets and zones from IPv6 literals.
- Remember both destIP and destPort must be valid together; an IP with port 0 skips parsing.
When it happens
Trigger: destIP is a hostname (e.g. 'example.com'), contains brackets/zone, or is otherwise unparsable while destPort != 0.
Common situations: Callers resolving the destination to a domain name instead of an IP before invoking process lookup, or tests passing placeholder destination strings.
Related errors
- invalid source 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/6ab9dcade34fd7ea.
Report an issue: GitHub.