Guides · September 2026
VS Code Remote SSH, set up and unstuck
The extension, the hosts it accepts, the config entry that makes connecting one click, the errors it throws, and the one limit no setting fixes.
What the extension actually does.
Remote - SSH — ms-vscode-remote.remote-ssh, from Microsoft, also in the Remote Development pack — opens an SSH connection to a machine, installs a small VS Code Server into ~/.vscode-server there, and from then on runs everything that touches files on that machine: the file tree, language servers, the debugger, extensions that need the code, and every integrated terminal. Your local VS Code becomes a window onto it. The server runs as the user you signed in as; VS Code installs and updates it to match the client’s version.
Locally: an OpenSSH-compatible ssh on the PATH — macOS and Linux have one, Windows 10 and 11 carry Microsoft’s as an optional feature. The host must be one the server runs on: 64-bit x86 Linux with glibc 2.28+, libstdc++ 3.4.25+ and kernel 4.18+ — Ubuntu 20.04+, Debian 10+, RHEL 8+, per the Linux prerequisites; ARM64 and 32-bit ARMv7 Linux, where some extensions ship x86-only native code; macOS 10.14+ with Remote Login on; or Windows 10 and Server 2016+ with the official OpenSSH Server. Alpine and other musl-based hosts are not supported over SSH. Microsoft recommends 2 GB of RAM and two cores; 1 GB is the floor.
Set it up.
The order matters: prove SSH in a terminal first, and the extension has nothing left to debug.
01Make ssh work on its own.
Connect from a terminal first. If this fails, the extension fails the same way with a less useful message.
ssh you@build-box02Install the extension.
Search Extensions for Remote - SSH, or install the Remote Development pack, which bundles it with Dev Containers, WSL, and Remote - Tunnels.
03Give the host a name in ~/.ssh/config.
Run Remote-SSH: Add New SSH Host… from the Command Palette, or Remote-SSH: Open SSH Configuration File… and write the entry yourself. Everything
sshunderstands is allowed, including a jump host withProxyJumpand port forwards that follow the connection.Host build-box HostName 10.0.0.12 User you IdentityFile ~/.ssh/id_ed25519 LocalForward 127.0.0.1:3000 127.0.0.1:3000 Host lab HostName lab.internal User you ProxyJump bastion~/.ssh/config 04Use a key, and an agent.
Passwords work, but VS Code does not save them and may open more than one SSH connection, so you will type it repeatedly. Make an Ed25519 key, put the public half in the host’s
~/.ssh/authorized_keys, and let an agent hold the passphrase —ssh-addon macOS and Linux; on Windows the OpenSSH agent service is disabled by default and needs enabling once from an administrator PowerShell.ssh-keygen -t ed25519 ssh-add ~/.ssh/id_ed25519 # Windows, administrator PowerShell: Set-Service ssh-agent -StartupType Automatic Start-Service ssh-agent05Connect and open a folder.
Remote-SSH: Connect to Host…, pick the entry, confirm the platform if asked, and wait for the server to install — a one-time download per VS Code version. Then File > Open Folder browses the remote filesystem; from a shell, the same thing is one command.
code --remote ssh-remote+build-box /home/you/project06Cut the repeated prompts on macOS and Linux.
Let OpenSSH multiplex and VS Code’s extra connections ride the first one, so a password or hardware-key touch is asked once. The docs offer this for macOS and Linux only; on Windows the agent is the fix.
Host build-box ControlMaster auto ControlPath ~/.ssh/cm-%r@%h:%p ControlPersist 10m~/.ssh/config
The errors, and what fixes them.
Start with Remote-SSH: Show Log; the last twenty lines usually name the cause. These come up most, checked against the VS Code troubleshooting guide and the extension’s issue tracker.
Could not establish connection to “host”: The VS Code Server failed to start
The SSH connection worked and the server did not. Run Remote-SSH: Kill VS Code Server on Host and reconnect; a half-installed server is the usual cause. If it repeats, check the glibc and libstdc++ floor above (ldd --version), that the home directory has space, and — common on shared machines — that ~/.vscode-server is not on an NFS or CIFS mount, where file locking hangs. Deleting ~/.vscode-server on the host is the clean reset.
Stuck on “Downloading VS Code Server”, or “Checking .log and .pid for a running server”
The host cannot reach Microsoft’s download servers, or the install is waiting on a prompt you cannot see. Set remote.SSH.localServerDownload to always so VS Code downloads the server locally and copies it over SSH — the route for locked-down hosts with no outbound internet. If the host has internet and still hangs, turn on remote.SSH.showLoginTerminal to reveal a password or MFA prompt the extension swallowed, and set remote.SSH.useLocalServer to false if it still never surfaces.
Permission denied (publickey), or a password prompt on every reconnect
Your key is not offered or not accepted. ssh -v you@host shows which keys were tried; make sure the agent is running and holds the key, and that the entry names the right IdentityFile. On a hardened host, AllowTcpForwarding yes must be set in sshd_config — the extension needs a forwarded port to reach the server, and a host that forbids forwarding fails in confusing ways.
Bad owner or permissions on C:\Users\you\.ssh\config
Windows only. OpenSSH refuses a config file whose permissions include inherited entries. From PowerShell, strip the inheritance and grant only your own account: icacls $env:USERPROFILE\.ssh /inheritance:r /grant:r "$($env:USERNAME):(F)" /t. Do not edit the file from an administrator window afterwards; that hands ownership to the wrong account.
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
The host’s key no longer matches ~/.ssh/known_hosts. After a rebuild of the machine, ssh-keygen -R hostname forgets the old key and the next connection asks you to accept the new one. If the machine was not rebuilt, do not accept it until you know why.
It connected yesterday and not today
VS Code updated itself, and the server on the host must match the new build. Usually that happens silently; when it does not, Kill VS Code Server on Host and reconnect installs the matching one.
The connection is the workspace.
One limit is worth understanding before you rely on the setup, because no setting removes it. Every integrated terminal in a Remote - SSH window is a process on the host, started by the VS Code Server for your window. VS Code’s persistent sessions cover two cases, and the terminal docs are exact: reload the window and the terminal reconnects to the same process; restart VS Code and its contents are restored but the process is relaunched. Relaunched, not resumed — the test run or the agent that was halfway through is not the one you get back.
Close the laptop for the afternoon and you are in the second case, or a third the docs promise nothing about: the connection drops, the window reconnects when it can, and what survived depends on the host’s sshd timeouts and how long the server waited. Anything that must keep running while you are not connected belongs in tmux, nohup, or a service on the host — not in the editor’s terminal. The phone does not help: vscode.dev is an editor, not a terminal. If you cannot open a port on the machine, Microsoft’s Remote Tunnels reach it through their service instead of SSH, with the same terminal limit.
Sessions that survive the lid.
The editor part of Remote - SSH is excellent and nothing here argues with it. The terminal part is where the shape runs out, exactly where agent work begins: a Claude Code refactor that takes an hour, a test loop, a build that finishes at 2am — jobs that must survive you leaving and want answering from wherever you are.
That is the job spawnd is shaped for, and it splits cleanly from the editor. One daemon on each host you own, dialing out — nothing listens on the host, no open ports, no VPN needed. A worker process on the host owns each session’s PTY, so a session survives the closed tab, the dropped connection, the laptop lid, and a daemon restart, scrollback intact. Any browser is the console, and on a phone it installs to the home screen as a web app; a new device is approved once against a short code. Your browser talks to each daemon peer-to-peer, end-to-end encrypted, and the server that introduces them never sees session content. Built-in shortcuts start Claude Code, Codex, OpenCode, or Aider in a real shell on the host, authenticated there as always; the workspace grid shows every session across every host, with an attention cue when an agent waits on a yes. Keep Remote - SSH for the editing; background agents defines the other half, and asks whose machine the agent is on.
Start
Edit in VS Code. Run the long things somewhere that stays up.
curl -fsSL https://spawnd.dev/install.sh | shQuestions
- Does Remote - SSH work with a Mac as the remote?
- Yes. The extension supports macOS 10.14 and newer as a host, provided Remote Login is on in System Settings > General > Sharing. The same key and config entry you use for a Linux host apply.
- Can I use Remote - SSH without opening a port on the host?
- SSH needs a path to port 22: the same network, a VPN such as Tailscale, or a jump host via
ProxyJump. Microsoft’s Remote Tunnels is the no-port alternative from the same team, routed through Microsoft’s service. For terminals alone, spawnd’s daemon dials out and needs neither. - Do my terminals keep running when I disconnect?
- Not reliably. A window reload reconnects to the same process; a VS Code restart relaunches it; a dropped connection is promised nothing. Long jobs go in tmux or a service on the host, or in a spawnd session, which a worker on the host owns by construction.