threads / discuss / 64601

UX failure: SSH authentication failure diagnostics

Subject: UX failure: SSH authentication failure diagnostics

## tl;dr

2 messages between Dec 9, 2025 and Dec 12, 2025.

replies: 1people: 2as markdown or json

Ryan Johnson· Dec 9, 2025, 05:08 UTC · lore

When Git fails SSH authentication, the error message provides no indication that Git may be using a different SSH client than the user expects.

PROBLEM
Multiple SSH implementations commonly coexist on a single system:
  Windows:
    - Windows OpenSSH: C:\Windows\System32\OpenSSH\ssh.exe
    - Git's bundled SSH: C:\Program Files\Git\usr\bin\ssh.exe
  macOS:
    - System SSH: /usr/bin/ssh
    - Homebrew SSH: /opt/homebrew/bin/ssh
  Linux:
    - System SSH: /usr/bin/ssh
    - Snap/Flatpak-packaged Git may bundle its own SSH
    - Alternative installations: /usr/local/bin/ssh

These may use separate key stores and agents. On Windows, the system ssh-agent service is inaccessible to Git's bundled MSYS2 SSH.

A user who runs:
  ssh -T git@github.com    # Works - uses one SSH binary
  git push                 # Fails - uses different SSH binary
receives only:
  git@github.com: Permission denied (publickey).
  fatal: Could not read from remote repository.

This error gives no indication that Git is using a different SSH binary than the one the user just tested. The user has no reason to suspect this is the cause. Debugging this issue typically costs hours of research.

SOLUTION
When SSH authentication fails, Git should:
1. Print which SSH command it invoked:
     Using SSH: /opt/homebrew/bin/ssh
2. Detect if multiple ssh binaries exist in PATH or common locations. If so:
     Note: Multiple SSH clients detected on this system.
     Git is using: C:\Program Files\Git\usr\bin\ssh.exe
     Also found:   C:\Windows\System32\OpenSSH\ssh.exe
     
     To use a different SSH client:
       git config --global core.sshCommand "/path/to/preferred/ssh"
This diagnostic should only appear on authentication failure, not on success.
RATIONALE

Git for Windows bundles MSYS2 tools for cross-platform consistency. Homebrew and Snap/Flatpak may install SSH binaries that shadow or conflict with system SSH. These are reasonable packaging decisions, but the resulting SSH client mismatch is a known, common failure mode that produces no actionable diagnostic information.

The fix is a one-line config change. The problem is that users have no way
to discover this without external research. Surfacing this information at
the point of failure would eliminate significant friction for beginners
as well as veterans. Seasoned programmers and beginners alike complain about
UX failures like this one all the time. Considering your tool has become de-facto
standard, you should take care of these problems. Dealing with this problem
 is the responsibility of the tooling creators, not the users. Do not shunt
responsibility onto every user to sit and spend an entire day of research and
headache unraveling your poorly-communicated configuration nuances.

-- Ryan

D. Ben Knoble· Dec 12, 2025, 21:46 UTC · re: Ryan Johnson · lore

Re: UX failure: SSH authentication failure diagnostics

On Tue, Dec 9, 2025 at 12:08 AM Ryan Johnson <ryan.johnson.code@gmail.com> wrote:

Show 37 quoted lines
>
> When Git fails SSH authentication, the error message provides no indication
> that Git may be using a different SSH client than the user expects.
>
> PROBLEM
>
> Multiple SSH implementations commonly coexist on a single system:
>
>   Windows:
>     - Windows OpenSSH: C:\Windows\System32\OpenSSH\ssh.exe
>     - Git's bundled SSH: C:\Program Files\Git\usr\bin\ssh.exe
>
>   macOS:
>     - System SSH: /usr/bin/ssh
>     - Homebrew SSH: /opt/homebrew/bin/ssh
>
>   Linux:
>     - System SSH: /usr/bin/ssh
>     - Snap/Flatpak-packaged Git may bundle its own SSH
>     - Alternative installations: /usr/local/bin/ssh
>
> These may use separate key stores and agents. On Windows, the system
> ssh-agent service is inaccessible to Git's bundled MSYS2 SSH.
>
> A user who runs:
>
>   ssh -T git@github.com    # Works - uses one SSH binary
>   git push                 # Fails - uses different SSH binary
>
> receives only:
>
>   git@github.com: Permission denied (publickey).
>   fatal: Could not read from remote repository.
>
> This error gives no indication that Git is using a different SSH binary than
> the one the user just tested. The user has no reason to suspect this is the
> cause. Debugging this issue typically costs hours of research.

I'm a bit confused on how this could be the case, but my knowledge here is admittedly murky: Git looks for SSH in the following places

- the value of GIT_SSH_COMMAND in the environment
- the value configured for core.sshcommand
- the value of GIT_SSH in the environment (historical compatibility,
according to source comments)
- finally, it uses the command "ssh" (which I assume is looked up in PATH)

Granted, Git does a little bit of PATH manipulation to find its own binaries, so is this the culprit? That might explain why the issue appears on Windows (bundled MSYS2 SSH)?

Show 19 quoted lines
>
> SOLUTION
>
> When SSH authentication fails, Git should:
>
> 1. Print which SSH command it invoked:
>
>      Using SSH: /opt/homebrew/bin/ssh
>
> 2. Detect if multiple ssh binaries exist in PATH or common locations. If so:
>
>      Note: Multiple SSH clients detected on this system.
>      Git is using: C:\Program Files\Git\usr\bin\ssh.exe
>      Also found:   C:\Windows\System32\OpenSSH\ssh.exe
>
>      To use a different SSH client:
>        git config --global core.sshCommand "/path/to/preferred/ssh"
>
> This diagnostic should only appear on authentication failure, not on success.

I think a simpler thing to do might be to make GIT_TRACE2* output lookup the pah for the command that's being run and log it, since I can see (using either GIT_TRACE2 or GIT_TRACE2_EVENT) the invocations of ssh for e.g. git-fetch. They just appear as "ssh" for me, although at the time of the trace events we don't know (at least on *nix) whether we're going to exec the program directly or fall back to executing it through the shell.

While poking at the exec calls, I saw we also have locate_in_PATH (non-Windows!), so perhaps we could also use that here. And we could add advice of the kind you mentioned (although I'm not sure it makes sense to search the system for other ssh implementations?), though it might not be the case that the solution to a failed SSH attempt is the client (it could be something else).

Stepping back a moment: I realized you wrote "When SSH authentication fails"---I'm not sure if Git sees that. I suspect it only sees that SSH failed ("could not read from remote"). And authentication could fail for any number of reasons. Hm. What to do?

Show 20 quoted lines
> RATIONALE
>
> Git for Windows bundles MSYS2 tools for cross-platform consistency. Homebrew
> and Snap/Flatpak may install SSH binaries that shadow or conflict with system
> SSH. These are reasonable packaging decisions, but the resulting SSH client
> mismatch is a known, common failure mode that produces no actionable
> diagnostic information.
>
> The fix is a one-line config change. The problem is that users have no way
> to discover this without external research. Surfacing this information at
> the point of failure would eliminate significant friction for beginners
> as well as veterans. Seasoned programmers and beginners alike complain about
> UX failures like this one all the time. Considering your tool has become de-facto
> standard, you should take care of these problems. Dealing with this problem
>  is the responsibility of the tooling creators, not the users. Do not shunt
> responsibility onto every user to sit and spend an entire day of research and
> headache unraveling your poorly-communicated configuration nuances.
>
> --
> Ryan

I can't speak for anyone else, but I find the statements at the end unhelpful to a fruitful collaboration for improvement. "Your tool", "you should", (paraphrasing) it's your problem, not mine… how are we to collaborate in such an atmosphere? (This kind of thing is where that trite "we don't owe you anything" comes from [1].) In a charitable reading, I'd just skip the last few sentences. It sounds like you've found a problem in documentation, or maybe in the way certain errors are presented. Great! Help us improve that for the next person, or maybe write down what you found and share it widely so others won't spend as much time researching the problem as you did.

[1]: https://mikemcquaid.com/open-source-maintainers-owe-you-nothing/
-- 
D. Ben Knoble

← back to recent threads