{"record":{"id":"332d61a15ef9f0b4","repo":"XTLS/Xray-core","slug":"failed-to-parse-pid","errorCode":null,"errorMessage":"failed to parse PID: ","messagePattern":"failed to parse PID: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/net/find_process_linux.go","lineNumber":79,"sourceCode":"\tpidStr, err := findPidByInode(inode)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"could not find PID for inode \", inode, \": \", err)\n\t}\n\tif pidStr == \"\" {\n\t\treturn 0, \"\", \"\", errors.New(\"no process found for inode \", inode)\n\t}\n\n\tabsPath, err := getAbsPath(pidStr)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"could not get process name for PID \", pidStr, \":\", err)\n\t}\n\n\tnameSplit := strings.Split(absPath, \"/\")\n\tprocName := nameSplit[len(nameSplit)-1]\n\n\tpid, err := strconv.Atoi(pidStr)\n\tif err != nil {\n\t\treturn 0, \"\", \"\", errors.New(\"failed to parse PID: \", err)\n\t}\n\n\treturn pid, procName, absPath, nil\n}\n\nfunc formatLittleEndianString(addr net.IP, port Port) (string, error) {\n\tip := addr\n\tvar ipBytes []byte\n\tif ip.To4() != nil {\n\t\tipBytes = ip.To4()\n\t} else {\n\t\tipBytes = ip.To16()\n\t}\n\tif ipBytes == nil {\n\t\treturn \"\", errors.New(\"invalid IP format for \", addr, \": \", ip)\n\t}\n\n\tfor i, j := 0, len(ipBytes)-1; i < j; i, j = i+1, j-1 {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/net/find_process_linux.go#L61-L97","documentation":"The PID string that findPidByInode produced could not be parsed by strconv.Atoi. findPidByInode derives pidStr from /proc directory names, which are always numeric, so in practice this fires only when pidStr came back malformed or the scan logic matched an unexpected entry. It is an internal-consistency failure, not a caller-input problem.","triggerScenarios":"A logic error or unexpected /proc layout (very old kernels, patched kernels with non-numeric entries) causing findPidByInode to return a non-numeric string; empty-string handling upstream would have hit the 'no process found' branch instead.","commonSituations":"Exotic or patched kernels with unusual /proc structures; essentially never on stock kernels. If you see it, capture pidStr from logs.","solutions":["Reproduce and log the exact pidStr value returned by findPidByInode to identify the malformed entry","Check the kernel's /proc layout (ls /proc | grep -v '^[0-9]*$') for anomalies","Treat as a non-fatal lookup failure and fall back to other routing rules","Report upstream to xray-core with the kernel version if reproducible"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":"func isPidParseError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to parse PID\")\n}","tryCatchPattern":"if err != nil && isPidParseError(err) {\n    // internal inconsistency; log pidStr context and continue without process info\n}","preventionTips":["Capture the offending pidStr in logs for an upstream report","Never seen on stock kernels — suspect a patched / exotic kernel"],"tags":["linux","process-lookup","internal-error","parsing"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}