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

  1. Read the chained error: EACCES/ENOENT mid-scan are mostly benign — re-check if a strict error policy turned them fatal
  2. Run the lookup with sufficient privileges (CAP_SYS_PTRACE or root) when cross-user matching is required
  3. Remove hidepid from the /proc mount or add the caller to a trusted group
  4. 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

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


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