Git pack-objects creates compressed archives of objects for efficient storage and transfer. When this operation fails, pushes, clones, and garbage collection break.

The Error

Attempting to push:

bash
git push origin main

You see:

bash
error: pack-objects died of signal 9
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly

Or during garbage collection:

bash
git gc
bash
fatal: pack-objects died with error
fatal: run_command: git pack-objects exited with status 128

Or during clone:

bash
git clone https://github.com/user/repo.git
bash
remote: fatal: pack-objects failed
fatal: early EOF
fatal: index-pack failed

Why Pack-Objects Fails

Common causes:

  • Memory exhaustion - Large repositories need significant memory
  • Disk space - Temporary files need space during packing
  • Object corruption - Damaged objects can't be packed
  • Process killed - Out-of-memory killer terminates process
  • Remote restrictions - Server-side limits reject large packs
  • Filesystem issues - Permission or space problems

Diagnosis Steps

Check repository size: ``bash git count-objects -v

Shows: `` count: 5000 size: 100 MiB in-pack: 10000 packs: 3 size-pack: 50 MiB prune-packable: 0 garbage: 0

Check loose objects: ``bash find .git/objects -type f ! -path "*.pack" ! -path "*.idx" | wc -l

Check available memory: ``bash free -h # Linux vm_stat # macOS

Check disk space: ``bash df -h .git/

Verify objects are valid: ``bash git fsck --full --progress

Solution 1: Increase Memory Limits

For large repositories, increase memory:

Set pack window memory: ``bash git config --global pack.windowMemory 100m

Set pack delta cache: ``bash git config --global pack.deltaCacheSize 100m git config --global pack.deltaCacheLimit 1000

Reduce compression for speed: ``bash git config --global pack.compression 0

Less compression uses less memory but creates larger packs.

Solution 2: Fix Disk Space Issues

Ensure adequate disk space:

Check space: ``bash df -h .

Pack-objects needs approximately 2x repository size during operation.

Clean up loose objects: ``bash git prune git gc

Remove old packs: ``bash # After verifying everything works git repack -a -d

Clear reflog: ``bash git reflog expire --expire=now --all git gc --prune=now --aggressive

Solution 3: Handle Process Killed (Signal 9)

If pack-objects is killed by OOM:

bash
dmesg | grep -i "killed process"

Shows: `` killed process 12345 (git-pack-objec), total-vm:2048000, anon-rss:1024000

Reduce pack size: ``bash git config --global pack.window 5 # Default is 10 git config --global pack.depth 50 # Default is 50 git config --global pack.threads 1 # Single thread uses less memory

Pack incrementally: ``bash git repack -d # Only repack necessary objects

Instead of: ``bash git repack -a -d # Repack all objects

Solution 4: Fix Object Corruption

If corrupt objects cause pack failure:

bash
git fsck --full

Shows: `` error: object file .git/objects/ab/c123... is empty missing blob abc123...

Remove corrupt objects: ``bash find .git/objects -type f -empty -delete

Fetch from remote: ``bash git fetch origin --all

Repack after repair: ``bash git repack -a -d

Solution 5: Handle Remote Restrictions

Server-side limits can reject large packs:

bash
remote: error: pack exceeds maximum allowed size (100 MiB)
fatal: The remote end hung up unexpectedly

Use smaller pack size: ``bash git config --global pack.windowMemory 50m

Push in smaller batches: ``bash # Push history incrementally git push origin <older-commit>:main git push origin <newer-commit>:main git push origin main

Use shallow push (if supported): ``bash git push --depth 100 origin main

Solution 6: Split Pack Files

For very large repositories:

bash
# Create multiple smaller packs
git repack -l -d --max-pack-size=100m

Or: ``bash git config --global pack.maxPackSize 100m git gc

Solution 7: Disable Delta Compression

Delta compression uses more memory:

bash
git config --global pack.window 0
git repack -a -d -f

No delta compression, larger pack files, less memory.

Solution 8: Fix Permission Issues

Permission problems can block pack creation:

bash
ls -la .git/objects/pack/

Fix permissions: ``bash chmod 755 .git/objects/pack/ chmod 644 .git/objects/pack/*.idx chmod 644 .git/objects/pack/*.pack

Solution 9: Use Alternate Object Store

For extremely large repos, use alternates:

bash
# Reference another repo's objects
echo "/path/to/shared-objects/.git/objects" > .git/objects/info/alternates

Verification

Verify pack creation works: ``bash git repack -d

Should complete without errors.

Check pack files: ``bash ls -la .git/objects/pack/ git verify-pack -v .git/objects/pack/*.idx

Test push: ``bash git push origin main --dry-run

Verify repository integrity: ``bash git fsck --full --progress

Prevention Strategies

Regular maintenance: ``bash git gc --auto # Runs automatically when needed

Or schedule: ``bash # Weekly aggressive gc git gc --aggressive --prune=now

Monitor repository health: ``bash git count-objects -v

Track object count and size over time.

Use git-lfs for large files: ``bash git lfs install git lfs track "*.psd" git lfs track "*.zip"

Removes large binaries from git object storage.

Configure appropriate limits: ``bash # For memory-constrained systems git config --global pack.windowMemory 256m git config --global pack.deltaCacheSize 256m git config --global pack.threads 2

Configuration Reference

```bash # Memory-related settings git config --global pack.windowMemory <bytes> # Max memory per window git config --global pack.deltaCacheSize <bytes> # Max delta cache git config --global pack.deltaCacheLimit <count> # Max deltas per object

# Pack-related settings git config --global pack.window <count> # Objects per window (default 10) git config --global pack.depth <count> # Max delta chain (default 50) git config --global pack.compression <level> # 0-9 (default 2) git config --global pack.threads <count> # Threads for packing

# Size-related settings git config --global pack.maxPackSize <bytes> # Max pack file size ```

Troubleshooting Large Repository Pushes

For pushing very large repositories:

```bash # Step 1: Optimize locally git gc --aggressive --prune=now

# Step 2: Use sparse checkout for large repos git config --global pack.window 5

# Step 3: Push with reduced threads GIT_TRACE=1 GIT_PACK_THREADS=1 git push origin main ```

Enable trace for debugging: ``bash GIT_TRACE=1 GIT_TRACE_PACK=1 git push origin main

Shows detailed pack-objects operations.