XTLS/Xray-core · warning

could not get process name for PID :

Error message

could not get process name for PID : 

What it means

A PID string was found for the socket inode, but reading its executable path (getAbsPath -> readlink /proc/<pid>/exe) failed; the underlying readlink error is appended. This is nearly always a race: the process exited between the FD scan and the exe readlink, or the caller lacks permission to read another user's /proc/<pid>/exe.

Source

Thrown at common/net/find_process_linux.go:71

	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)
	}

	return pid, procName, absPath, nil
}

func formatLittleEndianString(addr net.IP, port Port) (string, error) {
	ip := addr
	var ipBytes []byte
	if ip.To4() != nil {
		ipBytes = ip.To4()

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the appended error: ESRCH/ENOENT = process exited (benign race), EACCES = permission
  2. Retry the whole lookup once if the connection is still alive
  3. Run elevated when cross-user path resolution is needed
  4. Fall back to routing without the process name/path
Defensive patterns

Strategy: retry

Type guard

func isProcessNameError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "could not get process name for PID")
}

Try / catch

pid, name, path, err := net.FindProcess(netw, srcIP, srcPort, dstIP, dstPort)
if err != nil && isProcessNameError(err) {
    // /proc/<pid>/exe readlink raced with exit; one retry is cheap
    pid, name, path, err = net.FindProcess(netw, srcIP, srcPort, dstIP, dstPort)
}

Prevention

When it happens

Trigger: Matched process exits immediately after accepting/closing the connection; unprivileged caller matching a root process (readlink of /proc/<pid>/exe gives EACCES for foreign processes); zombie processes (exe link already gone).

Common situations: Short-lived connection handlers (per-request curl, forked workers); multi-user systems with process routing enabled.

Related errors


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