Skip to content

fix(windows): use unique named pipe paths derived from PM2_HOME#6104

Open
KYUUUW wants to merge 1 commit intoUnitech:masterfrom
KYUUUW:fix/windows-unique-pipe-names
Open

fix(windows): use unique named pipe paths derived from PM2_HOME#6104
KYUUUW wants to merge 1 commit intoUnitech:masterfrom
KYUUUW:fix/windows-unique-pipe-names

Conversation

@KYUUUW
Copy link
Copy Markdown

@KYUUUW KYUUUW commented Apr 8, 2026

Problem

On Windows, PM2 hardcodes named pipe paths to \.\pipe\rpc.sock, \.\pipe\pub.sock, and \.\pipe\interactor.sock (in paths.js line 84-87). Since Windows named pipes live in a flat global kernel namespace, this causes connect EPERM //./pipe/rpc.sock errors when:

The code already had a @todo comment acknowledging this:

//@todo instead of static unique rpc/pub file custom with PM2_HOME or UID

This issue has been reported since 2017 (#2946) and remains unfixed in PM2 6.0.14.

Solution

Derive a short hash from PM2_HOME and embed it in the pipe name:

var crypto = require('crypto');
var pipeId = crypto.createHash('md5').update(PM2_HOME).digest('hex').slice(0, 8);
pm2_file_stucture.DAEMON_RPC_PORT = '\\.\pipe\pm2-' + pipeId + '-rpc.sock';
pm2_file_stucture.DAEMON_PUB_PORT = '\\.\pipe\pm2-' + pipeId + '-pub.sock';
pm2_file_stucture.INTERACTOR_RPC_PORT = '\\.\pipe\pm2-' + pipeId + '-interactor.sock';

This ensures each PM2_HOME gets its own isolated set of IPC pipes, eliminating collisions.

What this fixes

  • Each user's PM2 instance uses unique pipe names based on their PM2_HOME path
  • No more EPERM from zombie pipes blocking the global name
  • Custom PM2_HOME directories work correctly on Windows
  • Zero impact on Linux/macOS (they use Unix domain sockets with PM2_HOME-relative paths)

Note

The same hardcoded pipe names also exist in @pm2/agent (constants.js line 93-96). That package needs a matching fix — happy to submit a PR there as well if you point me to the right repo.

Tested on

  • Windows 11 Pro (10.0.26200)
  • Node.js v24.14.0
  • PM2 6.0.14

Fixes #5510
Fixes #2946
Related: #5212, #3859, #4851

Windows named pipes live in a flat global namespace (\.\pipe\*).
The current hardcoded names (rpc.sock, pub.sock, interactor.sock)
cause EPERM errors when:

- Multiple users run PM2 on the same machine
- A zombie pipe from a crashed daemon blocks the name
- PM2 is started from different elevation levels (admin vs user)

This has been a known issue since 2017 (see Unitech#2946, Unitech#5212, Unitech#5510)
and the code already contained a @todo comment acknowledging it.

The fix derives a short hash from PM2_HOME and embeds it in the
pipe name (e.g. \.\pipe\pm2-a1b2c3d4-rpc.sock), ensuring each
PM2_HOME gets its own isolated set of IPC pipes.

Note: The same fix is needed in @pm2/agent/constants.js which
duplicates the Windows pipe name logic.

Fixes Unitech#5510
Fixes Unitech#2946

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 8, 2026

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-user support for PM2 daemon on Windows Error: connect EPERM //./pipe/rpc.sock

2 participants