{"record":{"id":"281a8f6e2e6249a2","repo":"XTLS/Xray-core","slug":"connection-for-not-found-in","errorCode":null,"errorMessage":"connection for :: not found in ","messagePattern":"connection for :: not found in ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"common/net/find_process_linux.go","lineNumber":58,"sourceCode":"\t\t\tprocFile = \"/proc/net/udp\"\n\t\t} else {\n\t\t\tprocFile = \"/proc/net/udp6\"\n\t\t}\n\tdefault:\n\t\tpanic(\"Unsupported network type for process lookup.\")\n\t}\n\n\ttargetHexAddr, err := formatLittleEndianString(net.ParseIP(srcIP), Port(srcPort))\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"failed to format address: \", err)\n\t}\n\n\tinode, err := findInodeInFile(procFile, targetHexAddr)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"could not search in \", procFile).Base(err)\n\t}\n\tif inode == \"\" {\n\t\treturn 0, \"\", \"\", errors.New(\"connection for \", srcIP, \":\", srcPort, \" not found in \", procFile)\n\t}\n\n\tpidStr, err := findPidByInode(inode)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"could not find PID for inode \", inode, \": \", err)\n\t}\n\tif pidStr == \"\" {\n\t\treturn 0, \"\", \"\", errors.New(\"no process found for inode \", inode)\n\t}\n\n\tabsPath, err := getAbsPath(pidStr)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"could not get process name for PID \", pidStr, \":\", err)\n\t}\n\n\tnameSplit := strings.Split(absPath, \"/\")\n\tprocName := nameSplit[len(nameSplit)-1]\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/net/find_process_linux.go#L40-L76","documentation":"The connection's local address:port (in /proc hex form) was searched successfully in the selected /proc/net table but no row matched, so no socket inode exists for it. The connection has already closed, or the address family selected the wrong table (udp vs udp6, tcp vs tcp6).","triggerScenarios":"Socket closed before lookup (very common for one-shot UDP sends); srcIP is IPv4-mapped IPv6 so To4() != nil selects /proc/net/udp while the socket actually lives in udp6; network namespace mismatch (caller and socket in different netns).","commonSituations":"Process routing on short-lived UDP queries (DNS); misconfigured dual-stack sockets; running inside a container while querying connections of the host.","solutions":["For UDP, look the socket up as close to send/receive time as possible, or skip process rules for UDP","Verify with ss -uanp | grep <port> that the socket still exists and note its actual family (v4 vs v6) and namespace","Make sure the Xray process runs in the same network namespace as the queried sockets","Treat as best-effort: fall back to other routing rules"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Confirm the socket still exists before lookup (Linux)\n// ss -uapn output parse, or simply: the faster path is to look up immediately on accept","typeGuard":"func isConnectionNotFound(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"not found in /proc/net\")\n}","tryCatchPattern":"if err != nil && isConnectionNotFound(err) {\n    // socket closed or wrong table; benign for short-lived UDP\n    return routeWithoutProcess(ctx)\n}","preventionTips":["Trigger lookup on connection accept, not on first data, to avoid closed-socket races","Skip process rules for UDP unless the socket is long-lived","Run in the same network namespace as the traffic being inspected"],"tags":["linux","process-lookup","race-condition","udp","network-namespaces"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}