XTLS/Xray-core · warning
connection for :: not found in
Error message
connection for :: not found in
What it means
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).
Source
Thrown at common/net/find_process_linux.go:58
procFile = "/proc/net/udp"
} else {
procFile = "/proc/net/udp6"
}
default:
panic("Unsupported network type for process lookup.")
}
targetHexAddr, err := formatLittleEndianString(net.ParseIP(srcIP), Port(srcPort))
if err != nil {
return 0, "", "", errors.New("failed to format address: ", err)
}
inode, err := findInodeInFile(procFile, targetHexAddr)
if err != nil {
return 0, "", "", errors.New("could not search in ", procFile).Base(err)
}
if inode == "" {
return 0, "", "", errors.New("connection for ", srcIP, ":", srcPort, " not found in ", procFile)
}
pidStr, err := findPidByInode(inode)
if err != nil {
return 0, "", "", errors.New("could not find PID for inode ", inode, ": ", err)
}
if pidStr == "" {
return 0, "", "", errors.New("no process found for inode ", inode)
}
absPath, err := getAbsPath(pidStr)
if err != nil {
return 0, "", "", errors.New("could not get process name for PID ", pidStr, ":", err)
}
nameSplit := strings.Split(absPath, "/")
procName := nameSplit[len(nameSplit)-1]
View on GitHub (pinned to 7d214f8b09)
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
Defensive patterns
Strategy: fallback
Validate before calling
// Confirm the socket still exists before lookup (Linux) // ss -uapn output parse, or simply: the faster path is to look up immediately on accept
Type guard
func isConnectionNotFound(err error) bool {
return err != nil && strings.Contains(err.Error(), "not found in /proc/net")
} Try / catch
if err != nil && isConnectionNotFound(err) {
// socket closed or wrong table; benign for short-lived UDP
return routeWithoutProcess(ctx)
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: Process routing on short-lived UDP queries (DNS); misconfigured dual-stack sockets; running inside a container while querying connections of the host.
Related errors
- could not find PID for inode :
- could not get process name for PID :
- process not found for connection from ::: to :
- could not get process path for PID :
- failed to determine if address is local:
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/281a8f6e2e6249a2.
Report an issue: GitHub.