跳到主要内容
ecdsa.com
git over HTTPS with libcurl-gnutls (Debian, Ubuntu)Git

错误信息

GnuTLS recv error (-110): The TLS connection was non-properly terminated.

也可能输出为

  • error: RPC failed; curl 56 GnuTLS recv error (-110): The TLS connection was non-properly terminated.

在 clone、fetch 和 push 期间,git 会把它包装为“error: RPC failed; curl 56 GnuTLS recv error (-110): …”;在 ls-remote 或第一个请求期间,它出现在“fatal: unable to access '<url>': ”之后。基于 OpenSSL 构建的 git 会把同样的事件报告为“OpenSSL SSL_read: … unexpected eof while reading”。

git over HTTPS with libcurl-gnutls (Debian, Ubuntu) — GNUTLS_E_PREMATURE_TERMINATION

含义

git 通过 HTTPS 接收数据时,TCP 连接关闭了,却没有发送标志着正常结束的 TLS close_notify 消息。GnuTLS(错误 -110,GNUTLS_E_PREMATURE_TERMINATION)把这种情况视为读取失败,因此 clone、fetch 或 push 会中止。证书没有问题;是某个环节在传输过程中切断了连接。

原因

修复方法

  1. 1.

    跟踪传输过程

    GIT_TRACE_CURL 会显示带时间戳的 HTTP 交互过程。如果失败发生在一个整齐的秒数之后,说明是超时;如果失败的时间点是随机的,说明是网络问题。

    bash
    # Where does the transfer stop? Time stamps show cut-offs at fixed timeouts.
    GIT_TRACE_CURL=1 GIT_TRACE_CURL_NO_DATA=1 git clone https://git.example.com/team/app.git 2>&1 | tail -40
  2. 2.

    减少单次请求的传输量

    部分克隆(--filter=blob:none),或者先浅克隆再执行 git fetch --unshallow,可以把工作拆分成更小的请求,降低触及限制的可能性。

    bash
    # Transfer less per request: shallow or partial clone, then fetch the rest
    git clone --filter=blob:none https://git.example.com/team/app.git
    git clone --depth 1 https://git.example.com/team/app.git && cd app && git fetch --unshallow
  3. 3.

    服务器所有者:调高代理超时和请求体大小限制

    为 Git 服务器前面的反向代理设置足以覆盖最大仓库的超时时间,并且不要限制 Git 端点的请求体大小。

    text
    # Reverse proxy in front of the Git server (nginx), for long clones and pushes
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    client_max_body_size 0;
  4. 4.

    用 SSH 代替 HTTPS

    如果 HTTPS 路径要经过一个会切断传输的代理,而 SSH 又是允许的,那么使用 SSH 远程仓库地址可以绕开这一跳。

    bash
    # Bypass the HTTPS path (and the proxy that cuts it) entirely
    git remote set-url origin git@git.example.com:team/app.git

相关错误

浏览完整的签名错误库