git - Server host key not cached

169k views Asked by At

I try to push changes from my local repo to a remote repo. When I type:

git push origin

I get the following error:

The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
Connection abandoned.
fatal: The remote end hung up unexpectedly

How can I solve this? I'm using git from the command line in Windows 7.

Edit

When I try to do a simple ssh

ssh user@hostname

I get the following error:

Could not create directory '/c//%HOMEDRIVE%%HOMEPATH%/.ssh'.
percent_expand: unknown key %H

Somehow it will not create the directory, because the path is invalid. How to fix this?

@eckes: Edit2

My Home is set to %HOMEDRIVE%%HOMEPATH% is this correct?

21

There are 21 answers

5
eckes On BEST ANSWER

The message means that the host key of origin is not present in your trusted hosts file.

To get around this, open a plain SSH connection to origin and SSH will ask you if you want to trust the remote host (from the Git console):

$ ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
RSA key fingerprint is <FINGERPRINT>.
Are you sure you want to continue connecting (yes/no)?

If you trust the remote host (i.e. type yes), SSH will add its key to the list of known hosts.

After that, you should be able to do your git push origin.

As an alternative, you could also manually add the key of origin to .ssh/known_hosts but this requires that you adhere to the format of the known_hosts file as described in the man page of sshd (Section AUTHORIZED_KEYS FILE FORMAT).

0
CoolMind On

I changed a hard disk, installed Windows. When tried to upload files received this command window.

I pressed "y", then Ctrl + C. Opened putty.exe, added an old key ther returned to git and pushed files.

1
Mateusz On

Had the same issue, and forget to connect to SSH on port where is actuall repository, not just general SSH port, then the host key is different!

0
Allen Jin On

I have tried all the methods above but none of them could fix the same issue on my laptop. Finally instead of pushing the branch to origin in git bash, I trun to use TortoiseGit's push option to do the pushing, then a window pops-up to ask me to add the new host key to cache, after clicking the yes button, everything goes fine now.

Hope it helps to you all.

1
sunilkumarba On

I too had the same issue when I was trying to clone a repository on my Windows 7 machine. I tried most of the answers mentioned here. None of them worked for me.

What worked for me was, running the Pageant (Putty authentication agent) program. Once the Pageant was running in the background I was able to clone, push & pull from/to the repository. This worked for me, may be because I've setup my public key such that whenever it is used for the first time a password is required & the Pageant starts up.

0
Henrik On

Solution with Plink

Save this python script to known_hosts.py:

#! /usr/bin/env python

# $Id$
# Convert OpenSSH known_hosts and known_hosts2 files to "new format" PuTTY
# host keys.
#   usage:
#     kh2reg.py [ --win ] known_hosts1 2 3 4 ... > hosts.reg
#       Creates a Windows .REG file (double-click to install).
#     kh2reg.py --unix    known_hosts1 2 3 4 ... > sshhostkeys
#       Creates data suitable for storing in ~/.putty/sshhostkeys (Unix).
# Line endings are someone else's problem as is traditional.
# Developed for Python 1.5.2.

import fileinput
import base64
import struct
import string
import re
import sys
import getopt

def winmungestr(s):
    "Duplicate of PuTTY's mungestr() in winstore.c:1.10 for Registry keys"
    candot = 0
    r = ""
    for c in s:
        if c in ' \*?%~' or ord(c)<ord(' ') or (c == '.' and not candot):
            r = r + ("%%%02X" % ord(c))
        else:
            r = r + c
        candot = 1
    return r

def strtolong(s):
    "Convert arbitrary-length big-endian binary data to a Python long"
    bytes = struct.unpack(">%luB" % len(s), s)
    return reduce ((lambda a, b: (long(a) << 8) + long(b)), bytes)

def longtohex(n):
    """Convert long int to lower-case hex.

    Ick, Python (at least in 1.5.2) doesn't appear to have a way to
    turn a long int into an unadorned hex string -- % gets upset if the
    number is too big, and raw hex() uses uppercase (sometimes), and
    adds unwanted "0x...L" around it."""

    plain=string.lower(re.match(r"0x([0-9A-Fa-f]*)l?$", hex(n), re.I).group(1))
    return "0x" + plain

output_type = 'windows'

try:
    optlist, args = getopt.getopt(sys.argv[1:], '', [ 'win', 'unix' ])
    if filter(lambda x: x[0] == '--unix', optlist):
        output_type = 'unix'
except getopt.error, e:
    sys.stderr.write(str(e) + "\n")
    sys.exit(1)

if output_type == 'windows':
    # Output REG file header.
    sys.stdout.write("""REGEDIT4

[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys]
""")

# Now process all known_hosts input.
for line in fileinput.input(args):

    try:
        # Remove leading/trailing whitespace (should zap CR and LF)
        line = string.strip (line)

        # Skip blanks and comments
        if line == '' or line[0] == '#':
            raise "Skipping input line"

        # Split line on spaces.
        fields = string.split (line, ' ')

        # Common fields
        hostpat = fields[0]
        magicnumbers = []   # placeholder
        keytype = ""        # placeholder

        # Grotty heuristic to distinguish known_hosts from known_hosts2:
        # is second field entirely decimal digits?
        if re.match (r"\d*$", fields[1]):

            # Treat as SSH-1-type host key.
            # Format: hostpat bits10 exp10 mod10 comment...
            # (PuTTY doesn't store the number of bits.)
            magicnumbers = map (long, fields[2:4])
            keytype = "rsa"

        else:

            # Treat as SSH-2-type host key.
            # Format: hostpat keytype keyblob64 comment...
            sshkeytype, blob = fields[1], base64.decodestring (fields[2])

            # 'blob' consists of a number of
            #   uint32    N (big-endian)
            #   uint8[N]  field_data
            subfields = []
            while blob:
                sizefmt = ">L"
                (size,) = struct.unpack (sizefmt, blob[0:4])
                size = int(size)   # req'd for slicage
                (data,) = struct.unpack (">%lus" % size, blob[4:size+4])
                subfields.append(data)
                blob = blob [struct.calcsize(sizefmt) + size : ]

            # The first field is keytype again, and the rest we can treat as
            # an opaque list of bignums (same numbers and order as stored
            # by PuTTY). (currently embedded keytype is ignored entirely)
            magicnumbers = map (strtolong, subfields[1:])

            # Translate key type into something PuTTY can use.
            if   sshkeytype == "ssh-rsa":   keytype = "rsa2"
            elif sshkeytype == "ssh-dss":   keytype = "dss"
            else:
                raise "Unknown SSH key type", sshkeytype

        # Now print out one line per host pattern, discarding wildcards.
        for host in string.split (hostpat, ','):
            if re.search (r"[*?!]", host):
                sys.stderr.write("Skipping wildcard host pattern '%s'\n"
                                 % host)
                continue
            elif re.match (r"\|", host):
                sys.stderr.write("Skipping hashed hostname '%s'\n" % host)
                continue
            else:
                m = re.match (r"\[([^]]*)\]:(\d*)$", host)
                if m:
                    (host, port) = m.group(1,2)
                    port = int(port)
                else:
                    port = 22
                # Slightly bizarre output key format: 'type@port:hostname'
                # XXX: does PuTTY do anything useful with literal IP[v4]s?
                key = keytype + ("@%d:%s" % (port, host))
                value = string.join (map (longtohex, magicnumbers), ',')
                if output_type == 'unix':
                    # Unix format.
                    sys.stdout.write('%s %s\n' % (key, value))
                else:
                    # Windows format.
                    # XXX: worry about double quotes?
                    sys.stdout.write("\"%s\"=\"%s\"\n"
                                     % (winmungestr(key), value))

    except "Unknown SSH key type", k:
        sys.stderr.write("Unknown SSH key type '%s', skipping\n" % k)
    except "Skipping input line":
        pass

Tested on Win7x64 and Python 2.7.

Then run:

ssh-keyscan -t rsa bitbucket.org >>~/.ssh/known_hosts
python --win known_hosts.py >known_hosts.reg
start known_hosts.reg

And choose to import into the registry. The keyscan will retrieve the public key for the domain (I had my problems with bitbucket), and then the python script will convert it to Plink format.

5
Roman Starkov On

For those of you who are setting up MSYS Git on Windows using PuTTY via the standard command prompt, the way to add a host to PuTTY's cache is to run

> plink.exe <host>

For example:

> plink.exe codebasehq.com

The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 2e:db:b6:22:f7:bd:48:f6:da:72:bf:59:d7:75:d7:4e
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)

Just answer y, and then Ctrl+C the rest.

Do check the fingerprint though. This warning is there for a good reason. Fingerprints for some git services (please edit to add more):

0
Kiran.vanam On

Just uninstall Git Extensions and Install again by choosing OpenSSH instead of

0
sadegh saati On

Just open Putty and try to establish connection to remote server you want to push your code. when the dialog appears press Yes(you trust remote) then everything would be OK.

1
Pyro2266 On

I solved similar problem using this workaround.

You just have to switch to Embedded Git, push, press Yes button and then switch back to System Git.

You can find this option in

Tools -> Options -> Git
0
jngcs On

I changed my SSH key and this happend. I tried some solution but it failed, and give up. Finally, I select the OpenSSH instead of PuTTY, then it works :)

0
rezsa f On

Rene, your HOME variable isn't set correctly. Either change it to c:\Users\(your-username) or just to %USERNAME%.

0
Reyhn On

As answered by Roman Starkov, plink needs to add the host to it's cache.

For people using Git Extensions:

  1. Open Git Extensions
  2. Go to Tools -> Settings -> SSH
  3. Copy the path to "plink.exe" (if using PuTTY) / "klink.exe" (if using KiTTY)
  4. In a console, run the following command:

(replace with the actual paths)

<the path to plink/klink.exe> <address to the server>

e.g.

%ProgramData%\chocolatey\lib\kitty\tools\klink.exe codebasehq.com

Note: Make sure to use the same plink/klink that Git Extensions is using!

1
79E09796 On

Changing from PuTTY to OpenSSH fixed this issue for me, without needing to unset GIT_SSH, etc.

0
Bart VdA On

Adding the host directly with Bash didn't solve the issue, the error still occurred when using 'Fetch all' in Git Extensions. By using 'Pull' on one branch, the required host was added automatically by Git Extensions with a Bash pop-up screen. After doing this I was able to use 'Fetch All' again. Not sure what is done by Git Extensions differently.

0
DonAriston On

In Windows 7 or 10, the trick that worked for me is deleting the GIT_SSH system variable. It was set before to use Plink, and now was replaced by Putty. This was causing Plink.exe error

There was also an old installation of Git (32-bit version) and updating to Git(e.g. Git-2.20.1-64-bit.exe) since the PC was 64-bit OS.

Anyway the Putty/Plink was not even used by Git since in the Git installation it was default to use Open SSH.

0
Rod Dewell On

If you receive the message about the unrecognized host key while doing git push/pull operations using ATLASSIAN SOURCETREE you do not have the ability to answer y/n and the push/pull operation will be aborted without caching the key. However going to SourceTree Tools->Options (General Tab) and changing the SSH Client under (under SSH Client Configuration) from PuTTY to OpenSSH will allow the key to be cached without changing anything else.

0
Jason 徐 On

Working environment:

  • Windows 10
  • git
  • putty

First: Delete putty known_hosts in registy according to the Regedit.
Then: Executing the command %GIT_SSH% user@hostname in Window's cmd solves the problem.

Hope it helps you all.

1
andynormancx On

Just ssh'ing to the host is not enough, on Windows at least. That adds the host key to ssh/known_hosts but the error still persists.

You need to close the git bash window and open a new one. Then the registry cache is cleared and the push/pull then works.

6
Thijs On

Try doing a "set | grep -i ssh" from the Git Bash prompt

If your setup is like mine you probably have these set:

GIT_SSH='C:\Program Files (x86)\PuTTY\plink.exe'
PLINK_PROTOCOL=ssh
SVN_SSH='"C:\\Program Files (x86)\\PuTTY\\plink.exe"'

I did a

unset GIT_SSH
unset PLINK_PROTOCOL
unset GIT_SVN

and it worked after that,.. I guess putty saves its keys somewhere else as $HOME/.ssh or something... (I've also had a problem on a box where $HOME was set to "C:\Users\usrnam" instead of "/C/Users/usrnam/"

anyway, your mileage may vary, but that fixed it for me. :-)

(probably just doing the unset GIT_SSH is enough, but I was on a roll)

Note: if unset doesn't work for you, try this:

set GIT_SSH=
2
Gunee On

I suspect that your GIT_SSH environment variable is set to %ProgramFiles(x86)%\putty\plink.exe. For some reason, PLink does not use the .ssh/known_hosts file in your user directory to store the remote hosts keys.

If this is actually your case, and it might be so on purpose if you want to use pageant, you need to use PLink to connect to the host first.

"$GIT_SSH" user@hostname

You should get a similar message

The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 86:7b:1b:12:85:35:8a:b7:98:b6:d2:97:5e:96:58:1d
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)

Once you have answered y to the question and successfully connected to the remote host, you should be all set. Go ahead and try your push again.