Find Questions…

Close ×
First time here? Check out the FAQ!

Only the top listed private key in Pageant is used/offered (by Git/SourceTree/TortoiseGit?).

Robertino Value asked this question · 6 karma ·

I spent a whole day trying to trace the source of this error :

QUOTE

Permission denied (publickey).

fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists."

UNQUOTE

I already tried all the usual suspects listed around the net, and at Atlassian and Github. To no avail.

I usually have about 8 - 10 SSH private keys loaded in Putty Pageant. And I do NOT get this error with Putty and WinSCP. With these 2, I can login over SSH with any number of different SSH identities, simultaneously.

But with TortoiseGit 1.8.0.0 (trying to login to just 1 account) I started seeing this error when I updated msysgit to 1.8.0.0.
I started creating my first 3 repos on Bitbucket 2 days ago. I had 10 SSH keys loaded in Pageant, and I was able to only connect to one Bitbucket account over SSH to push, etc. The other 2 received the error message above consistently.

The issue is easy to reproduce. Remove all private keys from the list in Pageant, and add just the 3 SSH identities meant for logging into Bitbucket. Any Git activity which requires login for the second and third keys will always fail. Remove the top key, and the second one (now at the top) will authenticate without issue. And the third on its own of course will always work. Doing this with just 2 private keys in the list (in all possible combinations of the 3 private keys) gives the same results. The one at the top is always used/offered to any request. Anything below it is not used/offered.

With only one of the 3 private keys in the list, there is never a problem as long as you attempt to login to the corresponding account. When attempting to login to a non-corresponding account, Pageant sometimes pops an error "Couldn't load this key (unable to open file)". After pressing OK to dismiss the error popup, the push would fail with the "Permission denied (public key)" error. I usually get this error when I try to load a public key into Pageant. That's why it's so weird.

I first saw this with TortoiseGit 1.8.0.0 and msysgit 1.8.0.0. Upgrading to 1.8.1.0 and 1.8.1.2 respectively didn't change a bit. So I blamed Tortoisegit and completely uninstalled and ran CCleaner to rid off most.

I installed SourceTree, and experienced the same problem. I have to make sure that the private key of the repo I want to work with is at the top of the list in Pageant. Which pretty much negates the multiple Repo tabs in SourceTree.

So I suspect that this is a Git problem. What I'm looking for is confirmation. I'm about to bury DVCS again, for another 3 years or so.

1708 views

2 Answers:

Steve Streeting [Atlassian] · 14,675 karma ·

[Reposting comment as an answer]

I've re-tested this and I can reproduce your case now, it only occurs when you have multiple *valid* keys for the host, ie keys that are associated with users on Bitbucket. And this now makes perfect sense, because what happens is that when you connect, BB asks for a key and Pageant passes the first one. Because that key *is* actually valid for a user on BB, it accepts it and logs you in as the user associated with that key. It then tries to get access to the repository - and fails because that user, while validly authenticated on BB, is not allowed access to that repo. It's only if the key that's passed to BB *isn't* a valid BB user than it moves on to try the next one.

I can actually reproduce this on the command line too, it's not a SourceTree issue. But then, I have my GIT_SSH pointing at plink.exe - I suspect that it's working for you in Git GUI because you're actually not using Plink/Pageant for that connection, perhaps you're using OpenSSH instead and there's some config for that that's resolving the ambiguity (IdentityFile).

One way to resolve this is to perform the same configuration in PuTTY too to disambiguate what key to send (and therefore which user to authenticate as).

  1. Start PuTTY (download it from putty.org if you don't have it)
  2. Type 'bitbucket.org' in the host name field
  3. Go to Connection > SSH > Auth in the tree
  4. Specify the key to use for the BB user
  5. Go back to 'Session' in the tree
  6. Type an alias name underneath 'Saved Sessions' (e.g. bb-user1) and Save
  7. Repeat 2-6 for each BB user and save as a different session name

Then in your remote URLs, replace 'bitbucket.org' with the session name (e.g. bb-user1) to disambiguate what SSH key to send first. This is identical to using IdentityFile in OpenSSH.

Steve Streeting [Atlassian] · 14,675 karma ·

BTW you still need to load these keys into Pageant if they have passphrases on them. This just makes sure the right key gets sent in the first instance.

Robertino Value · 6 karma ·

And this now makes perfect sense, because what happens is that when you connect, BB asks for a key and Pageant passes the first one. Because that key *is* actually valid for a user on BB, it accepts it and logs you in as the user associated with that key. It then tries to get access to the repository - and fails because that user, while validly authenticated on BB, is not allowed access to that repo.

Well this doesn't make sense at all to me :

configured at Bitbucket :

A/c 1, repo 1 origin : git@bitbucket.org:username1/username1.bitbucket.org.git + SSH-pubkey-1
A/c 2, repo 1 origin : git@bitbucket.org:username2/username2.bitbucket.org.git + SSH-pubkey-2
A/c 3, repo 1 origin : git@bitbucket.org:username3/reponame.git + SSH-pubkey-3
A/c 3, repo 2 origin : git@bitbucket.org:username3/username3.bitbucket.org.git + SSH-pubkey-3
configured in SourceTree :
Tab 1 has origin address : git@bitbucket.org:username1/username1.bitbucket.org.git
Tab 2 has origin address : git@bitbucket.org:username2/username2.bitbucket.org.git
Tab 3 has origin address : git@bitbucket.org:username3/reponame.git
Tab 4 has origin address : git@bitbucket.org:username3/username3.bitbucket.org.git

configured (in sequence) in PuTTY :
SSH-privatekey-1
SSH-privatekey-4
SSH-privatekey-2
SSH-privatekey-3
So at authentication from tab 1, BB receives pubkey-1 from PuTTY, encrypts challenge msg, sends encrypted msg to PuTTY, receives decrypted msg from PuTTY. Accesses Repo. OK!
Then at authentication from tab 2, The same. ERROR!
Then at authentication from tab 3, The same. ERROR!
Then at authentication from tab 4, The same. ERROR!
Why do I have to specify a different SSH key for each BB-account?
If BB is going to access the Repo only with the first SSH identity sent by PuTTY. And then gives up after the first fail. One and the same SSH key for all my accounts would have been sufficient.

Robertino Value · 6 karma ·

After a connection is established, BB should already know which SSH pubkeys are valid for that account (from the origin address).
So when PuTTY sends the public key to BB to initiate authentication, BB should already have detected whether the public key received, is a match or a mismatch.
So why can't BB refuse the key and ask PuTTY for another one?
(Before authentication, when possible, or after authentication.)
With PuTTY+Pageant I can login with the usernames administrator and Robert, and with WinSCP+Pageant and usernames root and webserver, all at the same server and simultaneously.
I refuse to believe that they were all logged in with the same SSH identity.

Robertino Value · 6 karma ·

I know for a fact that PuTTY can loop through the private keys loaded and authenticate with all that match the server. Because I bumped into the following problem a couple of years ago : http://the.earth.li/~sgtatham/putty/0.62/puttydoc.txt
10.5 Server sent disconnect message type 2 (protocol error): "Too many authentication failures for root"'
       This message is produced by an OpenSSH (or Sun SSH) server if it
       receives more failed authentication attempts than it is willing to
       tolerate.
       This can easily happen if you are using Pageant and have a large
       number of keys loaded into it, since these servers count each offer of a public key as an authentication attempt. This can be worked
       around by specifying the key that's required for the authentication in the PuTTY configuration (see section 4.20.8); PuTTY will ignore any other keys Pageant may have, but will ask Pageant to do the authentication, so that you don't have to type your passphrase.

       On the server, this can be worked around by disabling public-key
       authentication or (for Sun SSH only) by increasing `MaxAuthTries' in
       `sshd_config'.
Why can't SourceTree co-op with Pageant (like PuTTY and WinSCP) and ask for the next key until successful?
Or the second suggested option, store the path to a private key, per BB account, and ask Pageant to authenticate with that specific key?
(This is the reason that I can use PuTTY and WinSCP for multiple logins to the same server simultaneously.)
P.S.
About GitGui, I'm not aware of having setup any redirection or aliasing.

Robertino Value · 6 karma ·

I am going to accept your answer.

I'm also going to try the workaround you suggested with PuTTY.

But I'm adding that in my opinion it is a bit Spartan of SourceTree/Git/DVCS that it isn't possible to git to multiple accounts.

I'm probably ditching SSH keys for git usage altogether. It's faster to type a username and password, than to be a SSH key DJ.

Steve Streeting [Atlassian] · 14,675 karma ·

Perhaps that's best - it's because most Git servers use the SSH key not only for authentication, but to identify what user you are, which then means you have to be very specific about what key gets passed if you have multiple keys that are valid users on that same service. This isn't something SourceTree can really do anything about, it's just the nature of SSH key authentication on most git servers today.

Is there any reason you can't just use one SSH key / BB user and just be given access to the repositories via that? If you have different roles that need to be reflected in commits for each project, that's actually done via the commit name & email address separately to the authentication/authorization, so pushing/pulling via one central user wouldn't affect that.

Robertino Value · 6 karma ·

The reason is that I'm intending to handover an account at project rollout. Removing the public SSH key from the account. (And removing the [user]-block with user, email, signingkey from the repo config file.)

I was trying to save myself from having to clone repos to a newly created account, and (this is the big one) accumulating dormant repos in one account, and having to manage more repos than I could care for.

Monday, I'm having a go at the workaround with PuTTY which you suggested.

Steve Streeting [Atlassian] · 14,675 karma ·

Hmm, I can't reproduce this. I usually only have one key that I use, but I generated 2 others and tried a variety of orders and it didn't matter where my real key was in the list, it always got picked up. It seems that the Pageant list orders by bit length first, so after trying comment or key name that's how I eventually ordered them, although just in case I tried other combinations of fields too. It didn't matter, my proper key which was either 2nd or 3rd on the list always authenticated me fine.

I was testing with Bitbucket's SSH by the way. I don't know if it's possible that some servers only allow one key to be tried by the client before rejecting the connection, if so perhaps that's why you had this issue.

If that is the case then you may be able to make this more predictable by connecting though a PuTTY 'session' instead of the raw server name (session == alias) which specifies which key to send. You still need to use Pageant, but it will probably make it try the right key first. You do this by downloading the full PuTTY client from http://www.putty.org, running it then defining a session:

  1. Type the host name in the top field
  2. Go to SSH > Auth in the tree
  3. Specify the key in 'Private key file for authentication'
  4. Go back to the 'Session' section, type a session name under 'Saved Sessions' and click Save

Then you use this session name instead of the host name to connect, and it will pick up these settings.

Robertino Value · 6 karma ·

Apologies for the late reply, but I'm not getting email updates for this question. Strange.

You mention that you usually have one key that you use. That's why you're not getting the error because you're using the same SSH key for all repos/projects.

I'll be more specific. I have for instance 4 tabs/repos opened in SourceTree, across 3 Bitbucket accounts. This forces me to use 3 SSH keys. For example, I push to Bitbucket from tab 1. Pageant offers the corresponding private key, and all is well. But now I want to push to Bitbucket from tab 2 (another BB a/c), and it fails as described. Pushing to bitbucket from tabs 3+4 (yet another BB a/c) also fails. In this particular situation, I can only make git actions from tab 2, and tabs 3+4 work when I make sure that Pageant finds their key first. So I remove the SSH key for tab 1 from Pageant. Push from tab 2, and then add the SSH key for tab 1 again when I'm finished with tab 2. Same for tabs 3+4.

It looks like that on the very first git action (push, clone, whatever) the SSH key offered by Pageant is accepted and used for all opened tabs/repos.

That's also what's causing the confusion about the key sequence/order. The first git action always results in successful authentication. The problems start when after that, trying to simultaneously perform git actions to a repo with another SSH key.

Robertino Value · 6 karma ·

About what I wrote in my first post, "I have to make sure that the private key of the repo I want to work with is at the top of the list in Pageant.". I wrote "...at the top..." because I did not load the other 7 keys into Pageant. So there is always 1 Bitbucket SSH key at the top. When the other 7 keys are also in Pageant, the 3 BB keys sit somewhere in the middle, and still, only the first of the 3 is OK'ed. I was just taking the other 7 keys out of the equation to make things easier.

Like I mentioned at the end of my first post, for me, this pretty much negates the multiple Repo tabs in SourceTree. Especially, because after reporting this, I found out through trial and error that with Git Gui I can just start a new instance/session of Git Gui for each repo and can work on as many projects simultaneously as I want/can manage. As long as the keys are in Pageant. I thought that each SourceTree tab would be the equivalent of a Git Gui instance/session, without the clutter of 4/5 Git Gui windows opened.

Steve Streeting [Atlassian] · 14,675 karma ·

There isn't any relationship between tabs and keys used - all SourceTree ever does is call git commands, and git has absolutely no idea which tab that came from or the existing context - there's nowhere that we specify what SSH key to use for example.

I've re-tested this and I can reproduce your case now, it only occurs when you have multiple *valid* keys for the host, ie keys that are associated with users on Bitbucket. And this now makes perfect sense, because what happens is that when you connect, BB asks for a key and Pageant passes the first one. Because that key *is* actually valid for a user on BB, it accepts it and logs you in as the user associated with that key. It then tries to get access to the repository - and fails because that user, while validly authenticated on BB, is not allowed access to that repo. It's only if the key that's passed to BB *isn't* a valid BB user than it moves on to try the next one.

I can actually reproduce this on the command line too, it's not a SourceTree issue. But then, I have my GIT_SSH pointing at plink.exe - I suspect that it's working for you in Git GUI because you're actually not using Plink/Pageant for that connection, perhaps you're using OpenSSH instead and there's some config for that that's resolving the ambiguity (IdentityFile).

One way to resolve this is to perform the same configuration in PuTTY too to disambiguate what key to send (and therefore which user to authenticate as).

  1. Start PuTTY (download it from putty.org if you don't have it)
  2. Type 'bitbucket.org' in the host name field
  3. Go to Connection > SSH > Auth in the tree
  4. Specify the key to use for the BB user
  5. Go back to 'Session' in the tree
  6. Type an alias name underneath 'Saved Sessions' (e.g. bb-user1) and Save
  7. Repeat 2-6 for each BB user and save as a different session name

Then in your remote URLs, replace 'bitbucket.org' with the session name (e.g. bb-user1) to disambiguate what SSH key to send first. This is identical to using IdentityFile in OpenSSH.

Looking for something else?

Find Questions…

or Browse other questions tagged:

or Ask a Question