# UX failure: SSH authentication failure diagnostics

2 messages from 2025-12-09 to 2025-12-12. Participants: Ryan Johnson, D. Ben Knoble.
Thread: https://gitlist.dev/t/64601

## Ryan Johnson, 2025-12-09 05:08

Subject: UX failure: SSH authentication failure diagnostics
Message-ID: <DS0PR03MB729012244C8A65D318FDC205A3A3A@DS0PR03MB7290.namprd03.prod.outlook.com>
URL: https://gitlist.dev/e/DS0PR03MB729012244C8A65D318FDC205A3A3A%40DS0PR03MB7290.namprd03.prod.outlook.com

```
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, 2025-12-12 21:46

Subject: Re: UX failure: SSH authentication failure diagnostics
Message-ID: <CALnO6CDB8aHZ96emgX43GOVAzZxz_7-ZkOqhasob=zf+Hot0fw@mail.gmail.com>
URL: https://gitlist.dev/e/CALnO6CDB8aHZ96emgX43GOVAzZxz_7-ZkOqhasob%3Dzf%2BHot0fw%40mail.gmail.com
In-Reply-To: <DS0PR03MB729012244C8A65D318FDC205A3A3A@DS0PR03MB7290.namprd03.prod.outlook.com>

```
On Tue, Dec 9, 2025 at 12:08 AM Ryan Johnson
<ryan.johnson.code@gmail.com> wrote:
>
> 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)?

>
> 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?

> 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

```
