termal.in

← Blog

ssh-agent on Windows: start the service, add your keys, fix the errors

· Termalin Team sshssh-agentwindowstutorial

You put a passphrase on your SSH key, and now Windows asks for it on every git push and every ssh. The fix is the SSH agent — unlock the key once, and every connection after that signs silently. The twist on Windows is that there isn’t one agent. There are three that can be running at the same time, they hold keys in separate places, and a key loaded into one is invisible to the others. Almost every “it worked yesterday” agent problem on Windows is really a wrong agent problem. So this guide starts by naming them, then gets each one running, then decodes the errors you actually hit.

The three agents, and why they don’t share keys

AgentShips withWhere it listensWhich ssh sees it
OpenSSH Authentication Agent (a Windows service)Windows’ native OpenSSHnamed pipe \\.\pipe\openssh-ssh-agentssh.exe in C:\Windows\System32\OpenSSH
The MSYS2 agent (ssh-agent)Git for Windows / Git Basha Unix-style socket named by SSH_AUTH_SOCKthe ssh bundled inside Git Bash
A Linux agentinside your WSL distroa Unix socket in that distrossh running inside WSL

The lesson from the table: ssh-add in Git Bash loads a key into the MSYS2 agent, and the native Windows ssh.exe will never see it — different endpoint, different key store. Pick one agent, load your keys there, and use the matching ssh. Mixing them is the root cause of most of the confusion below. The ssh-agent and ssh-add guide covers the cross-platform mechanics; this page is the Windows-specific half.

The built-in OpenSSH Authentication Agent service

Modern Windows 10 and 11 ship OpenSSH, and with it a Windows service that runs the agent — but it’s off by default. Enable it once, from an elevated PowerShell (Run as administrator):

Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent

Automatic starts it on every boot, so this is a one-time setup. Check the result:

Get-Service ssh-agent | Select-Object Status, StartType

You want Running and Automatic. From then on, in a normal (non-Git-Bash) PowerShell or cmd, ssh-add talks to this service:

ssh-add                                 # load default keys (id_ed25519, id_rsa, …)
ssh-add $env:USERPROFILE\.ssh\id_ed25519  # load a specific key
ssh-add -l                              # list loaded key fingerprints

ssh-add -l is your first diagnostic for any login failure — if the key you expect isn’t listed, the agent can’t sign with it, whatever else looks right.

To stop retyping ssh-add, let the first connection load the key for you. Put this in %USERPROFILE%\.ssh\config (the same ssh_config file OpenSSH reads everywhere):

Host *
    AddKeysToAgent yes

Now the first ssh that needs a passphrase prompts once and loads the key into the service as a side effect. Because the native Windows git and ssh both use this service, git push starts working silently too.

Error 1058: “unable to start the ssh-agent service”

You run Start-Service ssh-agent and get:

Start-Service : Service 'OpenSSH Authentication Agent (ssh-agent)' cannot be started due to the following error:
Cannot start service ssh-agent on computer '.'.
... error 1058 ...

Error 1058 means the service is disabled — Windows won’t start a service whose Startup type is Disabled, and Start-Service doesn’t change that for you. Fix the startup type first, then start it (elevated PowerShell):

Set-Service ssh-agent -StartupType Manual
Start-Service ssh-agent

Manual is enough to start it on demand; use Automatic if you want it up on every boot. If you’re on a managed or domain machine, a group policy may have disabled it — in that case your admin has to allow the service before this sticks.

“error connecting to agent: No such file or directory”

This one comes from the Git Bash / MSYS2 ssh, not the Windows service. It means that ssh was told where to find an agent socket — via SSH_AUTH_SOCK — and nothing is there. Two common causes:

  • No agent is running in this shell. Git Bash doesn’t start one for you. Start it in the shell you’re using:

    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_ed25519

    The eval matters: ssh-agent -s only prints the variables; the eval sets them so ssh can find the socket. Running ssh-agent bare and wondering why nothing changed is the classic misstep.

  • SSH_AUTH_SOCK is stale. A variable set by a previous session, a login profile, or another tool points at a socket that no longer exists. Check it with echo $SSH_AUTH_SOCK, then either unset it and start a fresh agent, or fix it to point at a live one.

If you’d rather use the Windows service from inside Git Bash, call the native binary directly — /c/Windows/System32/OpenSSH/ssh.exe — instead of the MSYS2 ssh on your PATH. Then Git Bash reaches the same keys you loaded into the service, and SSH_AUTH_SOCK stops mattering.

Keys in WSL

WSL is a separate Linux system, so it has its own agent, its own ~/.ssh, and its own SSH_AUTH_SOCK. Keys loaded on the Windows side are not visible inside your distro, and vice versa. You have two honest choices:

  • Run an agent inside WSL the ordinary Linux way — eval "$(ssh-agent -s)" and ssh-add, or AddKeysToAgent yes in the distro’s ~/.ssh/config. Simple, fully isolated, and covered in the ssh-add guide.
  • Bridge to the Windows agent so both worlds share one key store. The usual recipe pipes the Windows named pipe into a Unix socket that WSL’s SSH_AUTH_SOCK points at, using npiperelay.exe together with socat. It works well once set up, but it’s extra moving parts — reach for it only if you genuinely need the same key on both sides.

Whichever you pick, remember that ssh-add -l inside WSL is a different question from ssh-add -l in PowerShell. Ask the right one when you debug.

When the agent is fine but login still fails

If ssh-add -l shows your key and the server still says Permission denied (publickey), the agent has done its job — the problem moved downstream to the server’s authorized_keys, the wrong user, or the wrong key being offered. That’s a separate checklist: Permission denied (publickey), fixed in order. And before you forward the agent to a remote box with ssh -A, read why agent forwarding is convenient and dangerous — it exposes live use of your keys on the far end.

How Termalin handles this on Windows

If juggling services, sockets and three key stores is more than you want to think about, that’s the workflow Termalin builds in. It runs its own key agent on a Windows named pipe, \\.\pipe\termalin-ssh-agent, and serves the keys you’ve already unlocked in the app over the standard ssh-agent protocol — so a tool that speaks that protocol can sign through it with no OS service to enable, no eval line, and no manual ssh-add. The private keys stay in the running app and are never written to disk. The point of that agent is to let Termalin’s own MCP server authenticate to your servers with your keys without ever holding the key material itself — the agent signs, the caller never sees the secret. It’s the same one-unlock idea as the OpenSSH service, with the Windows setup taken off your plate.


Termalin is a free, cross-platform SSH client whose built-in agent unlocks your keys once and signs on your behalf — download it, or read how it handles your keys safely.

Try it on one host.

Termalin is a fast SSH client for you — and your agents.

Free tier · 14-day Pro trial · pricing