错误信息
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 会中止。证书没有问题;是某个环节在传输过程中切断了连接。
原因
代理、防火墙或 NAT 网关断开了连接
常见设有连接时长或空闲时间限制的企业代理和防火墙、VPN 客户端以及一些家用路由器,会在不执行 TLS 关闭流程的情况下切断长时间运行的 HTTPS 传输。
Git 服务器或其反向代理超时
常见大型仓库在服务端打包需要一段时间。如果 GitLab、Gitea 或 Bitbucket 前面的 nginx、HAProxy 或负载均衡器的超时时间较短,连接会在 git 仍在等待时被关闭。
超大的 clone 或 push
偶见历史中包含大量二进制文件的仓库,会让传输量大到路径上的每一个时间或大小限制都会起作用。常见的建议是调大 http.postBuffer,但它只改变 git 发送请求体的方式,并不能阻止连接被切断。
不稳定的网络链路
偶见Wi-Fi 漫游、手机网络共享和拥塞的 VPN 链路都可能在传输中途重置连接;同一条命令重试一次或换用有线连接后就会成功。
修复方法
- 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.
减少单次请求的传输量
部分克隆(--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.
服务器所有者:调高代理超时和请求体大小限制
为 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.
用 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
相关错误
curl: (56) OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while…curl (OpenSSL 3 backend)error:0A000126:SSL routines::unexpected eof while readingOpenSSL 3fatal: unable to access 'https://git.example.com/team/app.git/': server verific…git over HTTPS with libcurl-gnutls (Debian, Ubuntu)