KhueApps
Home/DevOps/How to fix 'fatal: early EOF' during Git clone or fetch

How to fix 'fatal: early EOF' during Git clone or fetch

Last updated: October 07, 2025

Overview

The Git error "fatal: early EOF" usually means the connection closed before all data was received. It often appears with messages like "index-pack failed" or "The remote end hung up unexpectedly." This guide covers pragmatic fixes for CI and local DevOps workflows.

Quickstart: try a robust clone

If you just need a reliable clone on a flaky network or behind a strict proxy, try:

# Minimal working example: resilient shallow clone over HTTPS
URL="https://example.com/owner/repo.git"

git -c http.version=HTTP/1.1 \
    -c http.maxRequests=1 \
    -c http.lowSpeedLimit=1 \
    -c http.lowSpeedTime=600 \
    -c protocol.version=2 \
    clone --depth=1 --single-branch --no-tags "$URL" repo
  • HTTP/1.1 and maxRequests=1 avoid some HTTP/2/proxy quirks.
  • lowSpeedTime gives slow links more time before aborting.
  • Shallow clone reduces transferred data.

If it works, deepen later with git fetch --unshallow.

Why it happens

Common causes:

  • Intermittent network or aggressive corporate proxies closing idle streams.
  • HTTP/2 issues with middleboxes; multiplexed requests can be dropped.
  • Large repos; long transfer times trigger timeouts.
  • Antivirus or filesystem filters disrupting pack-file writes (often on Windows).
  • Git LFS objects not handled due to missing LFS client.
  • Server-side timeouts or resource limits.

Step-by-step troubleshooting

Follow in order; stop when the problem is resolved.

  1. Verify connectivity and URL
  • Test reachability:
# HTTPS
curl -I https://example.com/owner/repo.git/info/refs?service=git-upload-pack
# SSH
ssh -T [email protected] || true
  • Fix DNS/VPN/proxy first if these fail.
  1. Switch protocol (HTTPS ↔ SSH)
  • Try the other protocol to bypass proxy quirks.
# From HTTPS to SSH
git clone [email protected]:owner/repo.git
  • For SSH stability on long transfers, add keepalives:
# ~/.ssh/config
Host example.com
  ServerAliveInterval 30
  ServerAliveCountMax 10
  1. Reduce transferred data (shallow, single branch, no tags)
git clone --depth=1 --single-branch --no-tags https://example.com/owner/repo.git
  • Later, selectively deepen:
git fetch --deepen=200
  1. Tame HTTP behavior
  • Force HTTP/1.1 and serialize requests (helps with strict proxies):
git config --global http.version HTTP/1.1
git config --global http.maxRequests 1
  • Allow slow links more time before aborting:
git config --global http.lowSpeedLimit 1
git config --global http.lowSpeedTime 600
  • Ensure protocol v2 is enabled (more efficient fetch negotiation):
git config --global protocol.version 2
  1. Diagnose with verbose tracing
  • Enable curl and packet traces to pinpoint where it dies:
GIT_CURL_VERBOSE=1 GIT_TRACE_PACKET=1 GIT_TRACE=1 \
  git fetch --prune --progress origin
  • Look for proxy resets, HTTP/2 errors, or LFS URLs.
  1. Handle Git LFS objects
  • If LFS pointers are involved, install and fetch via LFS:
git lfs install
git lfs fetch --all
git lfs checkout
  1. Avoid local interference (Windows/macOS)
  • Exclude your repo directory from antivirus/endpoint scanning.
  • On Windows, ensure long paths are enabled:
git config --global core.longpaths true
  1. Clean and retry
  • Remove partial clone dir and retry with resilient settings:
rm -rf repo
git -c http.version=HTTP/1.1 -c http.maxRequests=1 \
    -c http.lowSpeedLimit=1 -c http.lowSpeedTime=600 \
    clone --depth=1 https://example.com/owner/repo.git repo
  1. Server-side considerations (contact admin if applicable)
  • Increase idle timeouts on reverse proxies.
  • Ensure Git HTTP backend supports protocol v2.
  • Check repo health; run git gc server-side.

Decision guide

SymptomLikely causeFix
Dies after long idleProxy/idle timeoutForce HTTP/1.1, increase lowSpeedTime, SSH keepalive
Fails only over HTTPSHTTP/2/proxy issuehttp.version=HTTP/1.1, maxRequests=1
Large repo, slow linkTransfer too bigShallow clone, single branch, no tags
Mentions LFSMissing LFS clientInstall Git LFS, run lfs fetch
Windows-onlyAV/FS filtersExclude repo, core.longpaths

Performance notes

  • Shallow clones are fastest but limit history-dependent operations; deepen incrementally as needed.
  • HTTP/1.1 may be slower than HTTP/2 where proxies are friendly; prefer HTTP/2 in clean environments.
  • Reducing http.maxRequests to 1 improves reliability through strict proxies but can reduce throughput.
  • Protocol v2 reduces round trips and bytes; keep it enabled.
  • Caching dependencies or using a nearby mirror dramatically lowers failures in CI.

Pitfalls to avoid

  • Do not rely on http.postBuffer: it affects pushes and is ignored for fetches in modern Git.
  • Avoid permanently disabling SSL verification; use only for narrow debugging if ever, then revert.
  • Don’t keep extreme lowSpeedTime settings globally if not needed; they can mask genuine stalls.
  • Shallow clones can break tooling that expects full history; plan a deepen step when required.

Minimal robust clone script (CI-friendly)

Use this snippet to retry a resilient shallow clone up to 3 times before failing.

set -euo pipefail
URL="$1"; DIR="${2:-repo}"
for i in 1 2 3; do
  rm -rf "$DIR"
  if git -c http.version=HTTP/1.1 \
         -c http.maxRequests=1 \
         -c http.lowSpeedLimit=1 \
         -c http.lowSpeedTime=600 \
         -c protocol.version=2 \
         clone --depth=1 --single-branch --no-tags "$URL" "$DIR"; then
    echo "Clone succeeded on attempt $i"; exit 0
  fi
  echo "Clone failed (attempt $i). Retrying..." >&2
  sleep 5
done
echo "Clone failed after 3 attempts" >&2
exit 1

Tiny FAQ

  • Q: I see "fatal: early EOF" and "index-pack failed". Related?
    • A: Yes. The pack download or unpack didn’t finish; fix the underlying transfer issue.
  • Q: Will increasing http.lowSpeedTime always help?
    • A: It helps slow links but won’t fix hard disconnects or proxy resets.
  • Q: Is http.postBuffer a fix?
    • A: No. It’s for pushes and is ineffective for clone/fetch in modern Git.
  • Q: Should I switch to SSH?
    • A: Often yes, especially behind proxies that meddle with HTTPS. Add keepalives.
  • Q: How do I confirm it’s a proxy issue?
    • A: Traces showing HTTP/2 stream resets or connections closing mid-transfer are strong indicators; testing from a different network can confirm.

Series: Git

DevOps