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
- Check the appended error: ESRCH/ENOENT = process exited (benign race), EACCES = permission
- Retry the whole lookup once if the connection is still alive
- Run elevated when cross-user path resolution is needed
- 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
- Budget exactly one retry for exit races
- Check for EACCES in the appended error to detect privilege issues instead of retrying them
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
- could not find PID for inode :
- 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/c2027f681ed45756.
Report an issue: GitHub.