microsoft / microsoft/vscode-remote-release
vs code fails to connect to remote ssh after update
Nobody has claimed this yet.
- Dominant language
- Dockerfile
- Stars
- 4.2k
- Forks
- 470
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 1
Description
Remote-SSH: askpass IPC socket path exceeds macOS sun_path limit, causing an endless reconnect loop
Environment
- VS Code: 1.128.1
- Remote-SSH: 0.122.0
- Local OS: macOS 26.5.2 (build 25F84), arm64
- Remote OS: Amazon Linux 2, kernel 5.10.260, x86_64
- Connection: SSH via a
ProxyCommandhelper
Summary
getIPCHandlePath() builds the askpass IPC socket path from os.tmpdir() plus a
40-hex-character random suffix. On macOS the resulting path is 113 characters, which
exceeds the 104-byte sun_path limit for AF_UNIX sockets. listen() fails with
EINVAL, the socket is never created, and the connection then falls into an
unbounded reconnect loop.
This is deterministic on macOS, not environment-specific. Apple's per-user temporary
directory has a fixed-width format:
/var/folders/<2>/<30>/T = 48 chars
/vscode-ssh-askpass-<40 hex>.sock = 65 chars
total = 113 chars (limit: 104)
The only call site is name = "askpass", and 20 random bytes is the default, so every
macOS user produces the same 113-character path.
Steps to reproduce
- On macOS, connect to any SSH host with Remote-SSH.
- Open the Remote-SSH output channel.
Expected
The askpass IPC socket is created and the connection remains stable.
Actual
The socket is never created and the connection loops. Relevant log excerpt:
stderr> local-server-3> listen EINVAL: invalid argument /var/folders/qt/<redacted>/T/vscode-ssh-askpass-<40hex>.sock
Server delay-shutdown request failed: connect EINVAL /var/folders/qt/<redacted>/T/vscode-ssh-askpass-<40hex>.sock - Local (undefined:undefined)
Server delay-shutdown request failed: connect EINVAL ... (repeats)
Exec server for ssh-remote+<host> closed (gracefully)
> local-server-3> Timed out
SSH Resolver called for "ssh-remote+<host>", attempt 8, (Reconnection)
The failure chain:
listen()on the askpass socket fails withEINVAL(path too long).- Because the socket does not exist, every
delay-shutdownrequest fails withEINVAL. - Without a successful
delay-shutdown, the local server times out after roughly five seconds. - The resolver reconnects, and the cycle repeats indefinitely.
The SSH transport itself is healthy throughout: authentication succeeds, the remote
server starts and reports a listening port, and the tunnel is established each time.
Only the local askpass socket fails.
Offending code
out/extension.js (and a duplicate copy in out/resolver.js):
getIPCHandlePath = async function (e, t = 20) {
const n = r.promisify(o.randomBytes);
return function (e, t) {
return "win32" === process.platform
? `\\\\.\\pipe\\vscode-ssh-${e}-${t}-sock`
: process.env.XDG_RUNTIME_DIR
? i.join(process.env.XDG_RUNTIME_DIR, `vscode-ssh-${e}-${t}.sock`)
: i.join(s.tmpdir(), `vscode-ssh-${e}-${t}.sock`); // <-- too long on darwin
}(e, (await n(t)).toString("hex"));
};
Note that XDG_RUNTIME_DIR is not set on macOS, so the os.tmpdir() branch is always taken.
Confirmed workaround
Replacing the base directory with /tmp in out/extension.js reduces the path to 69
characters and fully resolves the issue:
i.join("/tmp", `vscode-ssh-${e}-${t}.sock`)
After this change: the socket is created successfully, no EINVAL appears, the resolver
succeeds on attempt 1, and the connection is stable.
Worth noting for whoever picks this up: the utility is duplicated into both
out/extension.js and out/resolver.js by the bundler. Patching only resolver.js
has no effect, since package.json declares main: ./out/extension.
Suggested fixes
Either of these resolves it:
- Reduce the random suffix on non-Windows platforms. 8 bytes (16 hex characters) yields
an 89-character path, which fits. 20 bytes of entropy is more than a short-lived local
IPC socket needs. - Fall back to
/tmpon darwin whenos.tmpdir()would produce a path over the limit.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing getIPCHandlePath in out/extension.js and its duplicate in out/resolver.js, then check package.json to confirm the extension entry point. Reproduce the macOS Remote-SSH connection and verify the askpass socket path and listen result in the output log. Done means the socket is created within the AF_UNIX path limit and the resolver connects without repeated retries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js, vscode
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100