XTLS/Xray-core · warning

process not found for connection from ::: to :

Error message

process not found for  connection from ::: to :

What it means

MacOS FindProcess iterated every process and none of them owned a socket matching the given network/srcIP:srcPort (bestLevel stayed darwinSocketNoMatch). It means the connection either no longer exists, belongs to a process whose FDs could not be inspected, or the source address:port pair was wrong. This is a lookup miss, not a system failure.

Source

Thrown at common/net/find_process_darwin.go:118

		if matchLevel == darwinSocketExactMatch {
			bestPID = pid
			bestLevel = matchLevel
			ambiguousBest = false
			break
		}
		if matchLevel > bestLevel {
			bestPID = pid
			bestLevel = matchLevel
			ambiguousBest = false
			continue
		}
		if matchLevel == bestLevel {
			ambiguousBest = true
		}
	}

	if bestLevel == darwinSocketNoMatch {
		return 0, "", "", errors.New("process not found for ", network, " connection from ", srcIP, ":", srcPort, " to ", destIP, ":", destPort)
	}
	if ambiguousBest {
		return 0, "", "", errors.New("ambiguous process match for ", network, " connection from ", srcIP, ":", srcPort, " to ", destIP, ":", destPort)
	}

	absPath, err := darwinProcessPath(bestPID)
	if err != nil {
		return 0, "", "", errors.New("could not get process path for PID ", bestPID, ": ", err)
	}

	absPath = filepath.ToSlash(absPath)
	return int(bestPID), filepath.Base(absPath), absPath, nil
}

func darwinProcessSocketMatchLevel(pid int32, network string, srcAddr netip.Addr, srcPort uint16, dstAddr netip.Addr, dstPort uint16, hasDstAddr bool) (darwinSocketMatchLevel, error) {
	fds, err := darwinProcessFDs(pid)
	if err != nil {
		return darwinSocketNoMatch, err

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check that srcIP and srcPort actually describe an existing local socket (the 'from ::: to :' in the message indicates empty inputs upstream)
  2. Unmap IPv4-in-IPv6 addresses before calling, the same way the function does for destIP
  3. For UDP, ensure the socket is connected; unconnected UDP sockets may not match
  4. Retry the lookup once for short-lived connections, then fall back to non-process routing rules

Example fix

// before
if err != nil {
    return err
}

// after (best-effort: fall back when no process matches)
if err != nil {
    newError("no process for connection, fallback routing").Base(err).WriteToLog()
    return routeWithoutProcess(ctx)
}
Defensive patterns

Strategy: fallback

Validate before calling

if srcIP == "" || srcPort == 0 {
    // the 'from :::' message shape means inputs were empty; skip lookup
    return routeWithoutProcess(ctx)
}

Type guard

func isProcessNotFound(err error) bool {
    return err != nil && strings.Contains(err.Error(), "process not found for")
}

Try / catch

if _, _, _, err := net.FindProcess(netw, srcIP, srcPort, dstIP, dstPort); err != nil {
    if isProcessNotFound(err) {
        // benign: no owner matched, use other routing conditions
    }
}

Prevention

When it happens

Trigger: The socket was closed between connection acceptance and lookup (race, common for short-lived UDP); the query used a translated address (e.g. IPv4-mapped IPv6 that does not match the kernel's view); or darwinProcessFDs failed for the owning process, making it unmatchable. Note the empty srcIP/srcPort in the message template means the caller passed zero values.

Common situations: Routing rules that use process matching on fast-closing connections; calling FindProcess from a different network namespace or after NAT translation; invoking with unset source values (message shows 'from ::: to :').

Related errors


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