{"record":{"id":"4683f8ec184422d9","repo":"XTLS/Xray-core","slug":"process-not-found-for-connection-from-to","errorCode":null,"errorMessage":"process not found for  connection from ::: to :","messagePattern":"process not found for  connection from ::: to :","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"common/net/find_process_darwin.go","lineNumber":118,"sourceCode":"\t\tif matchLevel == darwinSocketExactMatch {\n\t\t\tbestPID = pid\n\t\t\tbestLevel = matchLevel\n\t\t\tambiguousBest = false\n\t\t\tbreak\n\t\t}\n\t\tif matchLevel > bestLevel {\n\t\t\tbestPID = pid\n\t\t\tbestLevel = matchLevel\n\t\t\tambiguousBest = false\n\t\t\tcontinue\n\t\t}\n\t\tif matchLevel == bestLevel {\n\t\t\tambiguousBest = true\n\t\t}\n\t}\n\n\tif bestLevel == darwinSocketNoMatch {\n\t\treturn 0, \"\", \"\", errors.New(\"process not found for \", network, \" connection from \", srcIP, \":\", srcPort, \" to \", destIP, \":\", destPort)\n\t}\n\tif ambiguousBest {\n\t\treturn 0, \"\", \"\", errors.New(\"ambiguous process match for \", network, \" connection from \", srcIP, \":\", srcPort, \" to \", destIP, \":\", destPort)\n\t}\n\n\tabsPath, err := darwinProcessPath(bestPID)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"could not get process path for PID \", bestPID, \": \", err)\n\t}\n\n\tabsPath = filepath.ToSlash(absPath)\n\treturn int(bestPID), filepath.Base(absPath), absPath, nil\n}\n\nfunc darwinProcessSocketMatchLevel(pid int32, network string, srcAddr netip.Addr, srcPort uint16, dstAddr netip.Addr, dstPort uint16, hasDstAddr bool) (darwinSocketMatchLevel, error) {\n\tfds, err := darwinProcessFDs(pid)\n\tif err != nil {\n\t\treturn darwinSocketNoMatch, err","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/net/find_process_darwin.go#L100-L136","documentation":"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.","triggerScenarios":"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.","commonSituations":"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 :').","solutions":["Check that srcIP and srcPort actually describe an existing local socket (the 'from ::: to :' in the message indicates empty inputs upstream)","Unmap IPv4-in-IPv6 addresses before calling, the same way the function does for destIP","For UDP, ensure the socket is connected; unconnected UDP sockets may not match","Retry the lookup once for short-lived connections, then fall back to non-process routing rules"],"exampleFix":"// before\nif err != nil {\n    return err\n}\n\n// after (best-effort: fall back when no process matches)\nif err != nil {\n    newError(\"no process for connection, fallback routing\").Base(err).WriteToLog()\n    return routeWithoutProcess(ctx)\n}","handlingStrategy":"fallback","validationCode":"if srcIP == \"\" || srcPort == 0 {\n    // the 'from :::' message shape means inputs were empty; skip lookup\n    return routeWithoutProcess(ctx)\n}","typeGuard":"func isProcessNotFound(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"process not found for\")\n}","tryCatchPattern":"if _, _, _, err := net.FindProcess(netw, srcIP, srcPort, dstIP, dstPort); err != nil {\n    if isProcessNotFound(err) {\n        // benign: no owner matched, use other routing conditions\n    }\n}","preventionTips":["Always populate srcIP/srcPort from the actual accepted connection metadata","Prefer calling the lookup immediately on connection acceptance, before the socket can close","Unmap IPv4-in-IPv6 addresses before matching"],"tags":["darwin","process-lookup","race-condition","socket-matching"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}