XTLS/Xray-core · warning
could not find PID for inode :
Error message
could not find PID for inode :
What it means
After finding the socket's inode, FindProcess scans /proc/<pid>/fd/* across all processes to find who owns it; that scan itself returned an error (chained after 'inode <n>:'). Typical wrapped causes are EACCES reading another user's /proc/<pid>/fd, or a directory vanishing mid-scan.
Source
Thrown at common/net/find_process_linux.go:63
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]
pid, err := strconv.Atoi(pidStr)
if err != nil {
return 0, "", "", errors.New("failed to parse PID: ", err)
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Read the chained error: EACCES/ENOENT mid-scan are mostly benign — re-check if a strict error policy turned them fatal
- Run the lookup with sufficient privileges (CAP_SYS_PTRACE or root) when cross-user matching is required
- Remove hidepid from the /proc mount or add the caller to a trusted group
- Fall back to non-process routing on failure
Defensive patterns
Strategy: fallback
Type guard
func isPidScanError(err error) bool {
return err != nil && strings.Contains(err.Error(), "could not find PID for inode")
} Try / catch
if err != nil && isPidScanError(err) {
// EACCES inside scan = hidden processes; fall back
} Prevention
- Run with adequate privileges when cross-user matching is required
- Do not enable process routing on systems with hidepid unless the caller is exempted
When it happens
Trigger: The socket belongs to a process of a different user and the caller lacks permission (unprivileged daemon reading root's FD table); a process exits while findPidByInode is iterating /proc.
Common situations: Running Xray as an unprivileged user with process-based routing for all system traffic; hidepid mount option hiding other users' processes entirely.
Related errors
- could not get process name for PID :
- could not search in
- connection for :: not found in
- no process found for inode
- failed to list processes
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/bd59e7858c39f770.
Report an issue: GitHub.