Fix Git Clone/Push Failure: error: RPC failed; curl 18 transfer closed with outstanding read data remaining

intermediate๐Ÿ“ฆ Git2026-05-03| Git 2.x on Linux, macOS, Windows โ€” typically occurs with large repositories over HTTP/HTTPS

Error Message

error: RPC failed; curl 18 transfer closed with outstanding read data remaining fatal: the remote end hung up unexpectedly
#git#clone#push#rpc#large-repo#http-buffer

What's Going On

You're cloning or pushing a repo, everything looks fine for a few seconds, then Git dies halfway through:

error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: the remote end hung up unexpectedly

The culprit is almost always repo size. Git's default HTTP buffer is just 1 MB. When a repo is large โ€” say, 500 MB with years of history and binary assets โ€” the server starts pumping data, the buffer fills up, the connection stalls, and the remote drops it.

Not a permissions issue. Not a firewall. A buffer/timeout mismatch between Git's HTTP layer and the remote server.

Debug: Confirm the Root Cause

Before touching any settings, verify what you're actually dealing with.

# Check current http.postBuffer setting (default is 1 MB = 1048576)
git config --global http.postBuffer

# No output means it's still at the 1 MB default

Then run the clone with full verbose logging to pinpoint exactly where it breaks:

GIT_CURL_VERBOSE=1 GIT_TRACE=1 git clone https://github.com/your/repo.git 2>&1 | tail -50

Scan for RPC failed, curl: (18), or transfer closed. Those three strings confirm it's a buffer issue โ€” and the fix below will solve it.

Solution 1: Increase the HTTP Post Buffer (Fix for Most Cases)

Start here. This single setting resolves roughly 90% of curl 18 failures.

# 500 MB โ€” handles most large repos
git config --global http.postBuffer 524288000

# 1 GB โ€” for repos over 1 GB or very long histories
git config --global http.postBuffer 1073741824

Retry the clone or push:

git clone https://github.com/your/repo.git
# or
git push origin main

Verification: No RPC error means it worked. Run git log --oneline -5 inside the cloned directory to confirm the history arrived intact.

Solution 2: Clone Shallow First, Then Fetch Full History

Some repos have 10,000+ commits. Even a 500 MB buffer isn't always enough for those. Clone with just the latest snapshot, then pull the rest in smaller bites.

# Download only the most recent commit โ€” fast and tiny
git clone --depth 1 https://github.com/your/repo.git

cd repo

# Fetch the full history in incremental chunks
git fetch --unshallow

The --depth 1 clone transfers maybe a few MB instead of the full history. Once you're inside with a stable connection, --unshallow fetches the rest gradually rather than in one massive burst that overwhelms the buffer.

Verification: After --unshallow finishes:

git log --oneline | wc -l
# Shows the full commit count โ€” not 1

Solution 3: Switch to SSH Instead of HTTPS

The curl 18 error only happens over HTTP. SSH uses a completely different transport โ€” no HTTP buffer, no RPC layer, no curl.

# Switch the remote URL from HTTPS to SSH
git remote set-url origin git@github.com:your-username/repo.git

# Confirm the change
git remote -v

# Retry
git push origin main
# or clone fresh:
git clone git@github.com:your-username/repo.git

SSH handles multi-gigabyte transfers without breaking a sweat. It's the most reliable long-term fix if you have SSH access. Corporate networks that block port 22 can sometimes tunnel SSH over port 443 โ€” check your Git host's docs for the ssh.github.com config.

Solution 4: Disable the Timeout and Lower Compression

Slow connections (think hotel WiFi, mobile hotspot, or a VPN bottleneck) trigger a different version of this error: the server cuts the connection after a timeout, not because the buffer filled. Two config changes help:

# Effectively disable Git's low-speed timeout
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

# Skip zlib compression โ€” larger transfers but less CPU overhead
git config --global core.compression 0

lowSpeedLimit 0 tells Git not to abort based on transfer speed. core.compression 0 trades file size for speed โ€” each object transfers a bit larger but doesn't need CPU time to compress first. On a slow connection where CPU isn't the bottleneck, this is almost always a net win.

Stack these settings on top of Solution 1's buffer increase for the best results on a sluggish network.

Solution 5: Push Commits in Smaller Batches

Clone works fine but git push keeps dying? You probably have a large backlog of commits โ€” common after working offline for a week or more. Push them in chunks instead of all at once.

# See what's waiting to be pushed
git log origin/main..HEAD --oneline

# Push the first ~100 commits
git push origin <hash-of-100th-commit>:main

# Push the rest normally
git push origin main

Grab the actual hash from git log output. If you have 400 unpushed commits, push them 100 at a time โ€” four smaller operations instead of one giant one that times out.

Checking Your Config After Fixes

See everything you've changed at once:

git config --global --list | grep -E 'http|core.compression'

With all fixes applied, you should see:

http.postbuffer=524288000
http.lowspeedlimit=0
http.lowspeedtime=999999
core.compression=0

Which Fix to Try First

  • Default starting point: Increase http.postBuffer (Solution 1) โ€” fixes 9 out of 10 cases.
  • Still failing: Add --depth 1 then --unshallow (Solution 2).
  • Have SSH access: Switch to SSH (Solution 3) โ€” most reliable permanently.
  • Slow or unstable connection: Pair Solution 4's timeout settings with the buffer increase.
  • Push-only problem: Push in batches (Solution 5).

Lessons Learned

Git's 1 MB default buffer dates from an era when most repos were small. Today's monorepos can hit 2โ€“5 GB. A project with ten years of history, a hundred contributors, and some committed binaries will easily transfer 300โ€“500 MB in a single clone operation โ€” 300ร— what the default buffer can handle.

Setting up a new dev environment? Add the buffer setting to your global config before you start cloning anything large. It takes five seconds and avoids this headache entirely.

Teams running very large repositories should also look at Git LFS to move binaries out of the main object store, and schedule periodic git gc --aggressive runs to pack loose objects. A well-maintained repo with LFS can cut clone size by 80% or more โ€” far less data to transfer means far fewer timeout problems.

Related Error Notes