Got connected to my remote dev server fine through VS Code’s Remote-SSH extension, terminal opened, everything looked normal — and then the second I tried to run a git pull inside that remote session, “Permission denied (publickey).” Which made no sense at first, since I’d literally just SSH’d in successfully. SSH key and Git authentication failures inside VS Code Remote-SSH almost always come down to your SSH agent not being forwarded to the remote host, meaning the connection to the server works but git operations on that server can’t reach the key sitting on your local machine. It’s a distinction that trips up a lot of people, myself included the first time.
So let’s go through why this happens and get your git operations actually working inside that remote session.
Quick Answer
- Check if SSH agent forwarding is enabled — this is the root cause most of the time
- Add
ForwardAgent yesto your SSH config for the relevant host - Confirm your key is actually loaded in your local agent with
ssh-add -l - Check the remote’s known_hosts and permissions on
~/.sshif forwarding is confirmed working but auth still fails - Restart the VS Code Remote-SSH extension host if changes to your SSH config aren’t being picked up
That covers most cases. There’s a second, less common category involving credential managers and GPG signing, covered further down.
Why This Happens — SSH Connection vs Git Authentication Are Different Things
This is the part that confuses people the most, honestly, and it’s worth understanding clearly before diving into fixes. Connecting to a remote host via Remote-SSH and running git commands on that remote host are two separate authentication events, even though they both involve “SSH.”
Local-to-remote connection works differently than remote-to-GitHub/GitLab connection. When VS Code connects you to your remote server, it’s using your local SSH key to authenticate you to that server. But once you’re inside that remote session and you run git pull or git push, the remote server itself needs a way to authenticate to GitHub or wherever your repo lives — and unless your key has been forwarded, the remote server has no key of its own to use.
SSH agent forwarding not enabled. This is the actual fix for the scenario above. Agent forwarding lets the remote server essentially “borrow” your local SSH agent’s loaded keys for the duration of your session, without ever copying the private key itself onto the remote machine. If it’s not configured, git auth on the remote will fail even though your initial SSH connection worked perfectly.
Keys not loaded into the local agent. Even with forwarding enabled, if your key isn’t actually loaded into your local SSH agent (via ssh-add), there’s nothing to forward. This happens more than you’d think, especially after a reboot, since a lot of systems don’t persist loaded agent keys across restarts by default.
Remote host’s known_hosts or permissions issues. Less common, but if the remote server’s SSH configuration or file permissions on ~/.ssh are wrong (should be 700 for the directory, 600 for private keys), SSH itself can refuse to use the forwarded credentials even when everything else is set up correctly.
Git credential manager conflicts. If you’re using HTTPS-based git remotes instead of SSH URLs, the issue is usually different — credential manager configuration, not SSH keys at all. This one gets mixed up with SSH key issues a lot because the error messages can look similar on the surface.
GPG signing key not forwarded. If your commits are set up to be GPG-signed, that’s yet another separate key that needs its own forwarding setup (gpg-agent forwarding, not ssh-agent), and it fails independently of whether your regular SSH auth is working.
Where This Shows Up Most
This is most common on fresh Remote-SSH setups, right after connecting to a new server for the first time, since agent forwarding isn’t the default behavior and has to be explicitly configured. It also shows up after switching machines or reinstalling VS Code, since local SSH config and agent state don’t always carry over cleanly.
It’s more of an issue on Windows using WSL2 combined with Remote-SSH than on plain macOS or Linux setups, from what I’ve seen, mostly because there’s an extra layer of agent forwarding happening between WSL and Windows itself that adds another place for things to break.
Common Causes Compared
| Cause | Symptom | Fix Difficulty | Notes |
|---|---|---|---|
| Agent forwarding disabled | SSH connects fine, git on remote fails | Easy | Most common cause by far |
| Key not loaded in local agent | Forwarding enabled but still fails | Easy | Check with ssh-add -l |
Remote ~/.ssh permissions wrong | Auth fails inconsistently on remote | Medium | Should be 700/600 |
| HTTPS remote credential issues | Different error pattern, not SSH-related | Easy | Check git credential manager instead |
| GPG signing not forwarded | Commits fail specifically at signing step | Medium | Separate from SSH auth entirely |
| VS Code extension host stale config | Config changes not applied | Easy | Restart the Remote-SSH extension host |
Step-by-Step Fixes
Step 1: Confirm the Problem Is Actually Agent Forwarding
Open a terminal inside your Remote-SSH session in VS Code and run ssh-add -l. If you see “Could not open a connection to your authentication agent” or it returns no keys at all, forwarding isn’t working, which points you straight at the fix below.
Step 2: Enable Agent Forwarding in Your SSH Config
On your local machine, edit ~/.ssh/config (not the remote’s config) and add ForwardAgent yes under the relevant Host entry:
Host myserver
HostName 192.168.1.100
User youruser
ForwardAgent yesAnd this needs to be on your local config, since forwarding is initiated from the client side, not the server side.
Step 3: Confirm Your Key Is Loaded Locally
Before connecting, run ssh-add -l on your local machine (not the remote) to confirm your key is actually loaded into your agent. If it’s not, run ssh-add ~/.ssh/your_key to load it. On macOS, you can add UseKeychain yes and AddKeysToAgent yes to your SSH config so this persists across restarts instead of needing to be done manually every time.
Step 4: Restart the Remote-SSH Connection
Config changes don’t always get picked up by an already-running Remote-SSH session. Use VS Code’s command palette (Ctrl+Shift+P or Cmd+Shift+P) and run “Remote-SSH: Kill VS Code Server on Host,” then reconnect. This forces a fresh session that picks up your updated config.
Step 5: Check Remote-Side Permissions If Forwarding Is Confirmed Working
If ssh-add -l inside the remote session now shows your key correctly but git operations still fail, check permissions on the remote with ls -la ~/.ssh — the directory should be 700 and any key files should be 600. SSH can silently refuse to work correctly with looser permissions than that.
Step 6: Check for HTTPS Remotes Instead of SSH
Run git remote -v inside your project on the remote server. If your URLs start with https:// instead of git@, this isn’t an SSH key problem at all — you’ll need to sort out git credential manager configuration on the remote instead, which is a different troubleshooting path entirely.
What Actually Worked For Me
My case was pretty much the textbook version of this — connected fine, git failed immediately after. Went looking for some exotic VS Code extension bug first, because that felt more interesting than “did you forget a config line,” and obviously found nothing, since that wasn’t actually the problem.
Circled back to basics and ran ssh-add -l inside the remote session, got the “no identities” response, and that was pretty much the whole answer right there. Added ForwardAgent yes to my local SSH config, killed the VS Code server on the remote host to force a clean reconnect, and it worked immediately after that. Felt a little anticlimactic honestly, given how much time I’d spent looking in more complicated directions first.
Second time I ran into something adjacent to this, it wasn’t forwarding at all — it was GPG commit signing failing specifically, while regular git pull/push worked completely fine. That one took longer to pin down since the error message didn’t obviously point at signing being the separate issue, and I initially assumed it was the same SSH forwarding problem all over again.
Advanced Fixes and Edge Cases
WSL2-specific agent forwarding. If you’re running Remote-SSH from Windows through WSL2, you need an agent bridge like npiperelay or the built-in WSL SSH agent forwarding support, since WSL2 and Windows don’t share an SSH agent natively. This is a genuinely separate setup step from the standard ForwardAgent yes config and easy to miss if you’re following generic (non-WSL) instructions.
GPG signing key forwarding. If commits fail specifically during signing rather than during push/pull, you need gpg-agent forwarding configured separately, which typically involves setting up a Unix socket forward in your SSH config pointed at your local GPG agent’s socket. This is a more involved setup than SSH agent forwarding and version-dependent enough that it’s worth checking current documentation for your specific GPG and OS combination.
Checking VS Code’s Remote-SSH logs directly. Command palette > “Remote-SSH: Show Log” gives you the actual connection and config parsing details VS Code used, which can reveal whether your SSH config is even being read correctly, especially useful if you suspect a syntax issue in ~/.ssh/config that’s silently being ignored.
Multiple keys causing the wrong one to be offered. If you’ve got several SSH keys loaded in your agent, SSH sometimes offers the wrong one first, and some git hosts will reject the connection after too many failed key attempts before ever trying the right key. Using IdentitiesOnly yes alongside an explicit IdentityFile in your SSH config forces SSH to only try the specific key you intend for that host.
Prevention Tips
- Enable
ForwardAgent yesas part of your standard SSH config setup for any host you’ll be doing git work on remotely, rather than adding it reactively after hitting this issue - Use
ssh-add -las a first troubleshooting step any time git auth fails in a remote session, before assuming it’s something more complicated - Keep GPG signing setup documented separately from your basic SSH auth setup, since they fail independently and get confused for each other easily
- Avoid loading unnecessary extra keys into your agent if you’re hitting “too many authentication failures” errors on hosts with strict connection attempt limits
FAQ
Is agent forwarding a security risk? It carries some risk if the remote server is compromised, since a compromised remote could technically use your forwarded agent while your session is active, though it can’t extract your actual private key. Only enable it for hosts you genuinely trust.
Why does my SSH connection work but git on the remote fails? Because those are two separate authentication steps — your SSH connection authenticates you to the remote server, but git operations on that server need to separately authenticate to GitHub/GitLab, which requires forwarding.
Do I need to restart VS Code entirely, or just the Remote-SSH session? Usually just killing the VS Code server on the remote host and reconnecting is enough — a full VS Code restart isn’t typically necessary unless something’s more deeply stuck.
Does this apply the same way to GitLab and Bitbucket, not just GitHub? Yes, the underlying SSH agent forwarding mechanism doesn’t care which git host you’re authenticating to — the same fix applies regardless of provider.
Why did this start happening after I switched from a wired connection to WSL2? WSL2 doesn’t share your Windows SSH agent automatically, so you’ll need a bridging tool or WSL-specific agent forwarding setup that wasn’t necessary before.
Editor’s Opinion
ssh-add -l shouldve been the first thing i checked instead of like the fifth, classic case of assuming the complicated explanation before the boring one. forwarding agent stuff always gets me for some reason, feels like i relearn this every six months instead of it actually sticking. write it down somewhere you’ll actually find again, past me clearly didnt
