Skip to content
ecdsa.com
git over HTTPS with libcurl-gnutls (Debian, Ubuntu)Git

Error message

fatal: unable to access 'https://git.example.com/team/app.git/': server verification failed: certificate signer not trusted. (CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none)

Also printed as

  • server verification failed: certificate signer not trusted. (CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none)
  • server certificate verification failed. CAfile: none CRLfile: none

The URL is your remote. Older Debian and Ubuntu releases (libcurl 7.x) print the shorter "server certificate verification failed. CAfile: none CRLfile: none", where "CAfile: none" only means no explicit CA file was configured and the system bundle was used.

What it means

git's HTTPS transport (libcurl built against GnuTLS on Debian and Ubuntu) could not verify the Git server's certificate: no certificate in the chain leads to a CA in the bundle it reads. "certificate signer not trusted" is GnuTLS's way of saying the issuer is unknown; nothing about your credentials or the repository was checked yet.

Why it happens

How to fix it

  1. 1.

    See which certificates the Git server sends

    If only the leaf appears, fix the server. If the chain ends at a company or proxy root, install that root on the client.

    bash
    openssl s_client -connect git.example.com:443 -servername git.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'
  2. 2.

    Trust a CA for one Git server

    http.<url>.sslCAInfo limits the custom CA to one host, so public remotes keep using the system bundle. GIT_SSL_CAINFO does the same for a single command or CI job.

    bash
    # Trust the company CA for this server only; other remotes keep the system bundle
    git config --global http."https://git.example.com/".sslCAInfo /etc/ssl/private-ca/corp-root-ca.pem
    git ls-remote https://git.example.com/team/app.git
  3. 3.

    Add the root to the system bundle

    Installing the root through update-ca-certificates fixes git, curl, wget and package managers in one step. In Docker images, do it in the Dockerfile; in CI, in the runner image.

    bash
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt
    sudo update-ca-certificates     # git, curl and wget read /etc/ssl/certs/ca-certificates.crt
  4. 4.

    Server owners: configure the full chain

    The certificate file used by the Git server's web front end must contain the leaf followed by every intermediate.

    text
    # GitLab Omnibus (/etc/gitlab/gitlab.rb): the .crt file must contain leaf + intermediates
    nginx['ssl_certificate'] = "/etc/gitlab/ssl/git.example.com.crt"
    # then: sudo gitlab-ctl reconfigure
  5. 5.

    Temporary diagnostic: skip verification for one command

    -c http.sslVerify=false for a single command confirms that trust is the only problem. Setting it globally sends your credentials and code to anyone who can intercept the connection.

    bash
    # Diagnostic only, for one command: never set http.sslVerify=false globally
    git -c http.sslVerify=false ls-remote https://git.example.com/team/app.git

Related errors

Browse the full signature error database