Troubleshooting ‘Git error pack-objects died of signal 13 pipe break’ during Large Pushes on Ubuntu 20.04 LTS
Resolve 'pack-objects died of signal 13' Git errors during large pushes on Ubuntu 20.04 LTS. This guide addresses SSH timeouts, HTTP buffer limits, and Git pack configurations.
Resolve 'pack-objects died of signal 13' Git errors during large pushes on Ubuntu 20.04 LTS. This guide addresses SSH timeouts, HTTP buffer limits, and Git pack configurations.
Introduction
Encountering a "Git error pack-objects died of signal 13 pipe break" message during a large git push operation can be a frustrating experience for developers and system administrators. This cryptic error indicates that the pack-objects process, responsible for efficiently compressing and transferring Git objects, received a SIGPIPE signal, meaning one end of the communication pipe closed unexpectedly while the other was still attempting to write data. This often occurs when pushing repositories with a substantial number of files, very large individual files, or extensive commit histories, as the transfer duration and resource demands increase, making the connection more susceptible to timeouts or resource exhaustion.
This guide provides a comprehensive, highly technical approach to diagnose and resolve this issue on Ubuntu 20.04 LTS systems, covering common culprits from SSH server configurations to Git client and server settings.
Symptom & Error Signature
When attempting to push a large volume of data to a remote Git repository, typically via SSH or HTTPS, the push operation fails with an error similar to the following:
Enumerating objects: 1234567, done.
Counting objects: 100% (1234567/1234567), done.
Delta compression using up to 8 threads
Compressing objects: 100% (1234560/1234560), done.
Writing objects: 100% (1234567/1234567), 9.87 GiB | 10.00 MiB/s, done.
Total 1234567 (delta 987654), reused 1234567 (delta 987654)
error: remote unpack failed: unable to create temporary file: No space left on device
fatal: the remote end hung up unexpectedly
fatal: the remote end hung up unexpectedly
error: pack-objects died of signal 13
The specific error error: pack-objects died of signal 13 is the key indicator, often accompanied by fatal: the remote end hung up unexpectedly or other remote-related messages. While No space left on device might appear in some contexts, the SIGPIPE (signal 13) error specifically points to a broken communication channel rather than storage capacity.
Root Cause Analysis
The "pack-objects died of signal 13" error is fundamentally a SIGPIPE (Pipe Broken) signal received by the pack-objects process. This signal indicates that the process attempted to write to a pipe or socket whose reading end has been closed. In the context of Git pushes, this can stem from several underlying issues:
SSH Server Timeouts (Most Common for SSH Remotes):
- During prolonged data transfers, the SSH server (sshd) might terminate an "inactive" connection if no activity (or keep-alive packets) is observed for a configured duration. This is governed by
ClientAliveIntervalandClientAliveCountMaxinsshd_config. When the SSH connection is closed prematurely, the pipe breaks, and the client-sidepack-objectsprocess receivesSIGPIPE.
- During prolonged data transfers, the SSH server (sshd) might terminate an "inactive" connection if no activity (or keep-alive packets) is observed for a configured duration. This is governed by
HTTP/S
postBufferLimits (Most Common for HTTP/S Remotes):- When pushing over HTTP/S, Git clients use HTTP POST requests to send packed objects. Web servers (e.g., Nginx, Apache) or Git's internal HTTP server might have limitations on the size of the request body or an upload timeout. If the packed objects exceed the
http.postBuffersetting on the client or the server, or if the transfer takes too long, the connection can be reset.
- When pushing over HTTP/S, Git clients use HTTP POST requests to send packed objects. Web servers (e.g., Nginx, Apache) or Git's internal HTTP server might have limitations on the size of the request body or an upload timeout. If the packed objects exceed the
Network Instability or Intermediate Device Timeouts:
- Firewalls, proxies, load balancers, or NAT devices between the client and the Git server often have their own idle connection timeouts. A long-running Git push, especially over a flaky network, can exceed these timeouts, leading to a connection reset and a
SIGPIPE.
- Firewalls, proxies, load balancers, or NAT devices between the client and the Git server often have their own idle connection timeouts. A long-running Git push, especially over a flaky network, can exceed these timeouts, leading to a connection reset and a
Server-side Resource Exhaustion:
- While less direct for
SIGPIPE, severe memory pressure, disk I/O bottlenecks, or hittingulimitrestrictions on the Git server can cause processes to hang, be killed by the OOM (Out Of Memory) killer, or fail to respond, indirectly leading to the client's connection breaking and aSIGPIPE. Thepack-objectsprocess can be memory-intensive.
- While less direct for
Corrupted Repository or Git Installation:
- Though rarer for
SIGPIPE, a severely corrupted local or remote repository, or issues with the Git installation itself, could theoretically lead to unexpected process termination.
- Though rarer for
Step-by-Step Resolution
Address these issues methodically, starting with the most common causes based on your remote protocol (SSH or HTTP/S).
1. Adjust Git HTTP Post Buffer (Client-side)
If you are pushing over HTTP/S, the client's http.postBuffer might be too small for large packs. This setting dictates the maximum size of the HTTP POST buffer Git will use when sending data.
Increase
http.postBufferglobally: Open your global Git configuration file (~/.gitconfig):git config --global http.postBuffer 524288000 # 500 MBYou can adjust
524288000(bytes) to a larger value like1048576000(1 GB) if necessary.Increase
http.postBufferfor a specific repository: Navigate to your repository and set it locally:cd /path/to/your/repo git config http.postBuffer 524288000
This change only affects HTTP/S pushes. If your remote URL starts with
git@orssh://, this setting will not apply.
2. Adjust Git HTTP Post Buffer (Server-side)
If your Git server uses HTTP/S (e.g., self-hosted GitLab, Gitea, or a plain Git daemon fronted by Nginx/Apache), the server-side http.postBuffer or web server upload limits might be the bottleneck.
For Git servers using Git smart HTTP: On the server, if you manage a raw Git HTTP endpoint, you might need to adjust
http.postBufferin the server's global Git config or repository config, similar to the client-side. Alternatively, check the web server configuration.For Nginx (Common for GitLab/Gitea): Increase the
client_max_body_sizedirective in your Nginx configuration for the Git host. This is typically found in/etc/nginx/nginx.conf,/etc/nginx/sites-available/your-git-host, or similar.# In http, server, or location block client_max_body_size 500M; # Or 1G, 2G depending on your needs client_body_timeout 300s; # Increase timeout for large uploads send_timeout 300s;After modification, test the Nginx configuration and reload/restart:
sudo nginx -t sudo systemctl reload nginxFor Apache (Less common for modern Git services but applicable): Adjust
LimitRequestBodyandTimeoutdirectives in your Apache configuration for the Git virtual host or directory.# In VirtualHost or Directory block LimitRequestBody 0 # 0 for unlimited, or a specific byte size (e.g., 524288000 for 500MB) Timeout 300 # Increase timeoutReload/restart Apache:
sudo systemctl reload apache2
3. Adjust SSH Server Keep-Alive Settings (Server-side)
This is a critical step for repositories accessed via SSH (e.g., [email protected]:user/repo.git). The SSH server might be terminating the connection due to perceived inactivity.
Edit
sshd_configon the Git server: Connect to your Git server (the machine hosting the repository) via SSH. Open thesshd_configfile using a text editor:sudo nano /etc/ssh/sshd_configAdd or modify
ClientAliveIntervalandClientAliveCountMax: Add or uncomment and set the following lines. These settings send null packets to the client everyClientAliveIntervalseconds, and if no response is received afterClientAliveCountMaxintervals, the connection is terminated.ClientAliveInterval 60 ClientAliveCountMax 10This configuration will send a keep-alive message every 60 seconds and will terminate the connection only after 10 failed attempts (i.e., after 600 seconds or 10 minutes of unresponsiveness). You can increase
ClientAliveCountMaxfor even longer tolerance.
Be mindful when setting
ClientAliveIntervalto very low values, as it can increase network traffic slightly. However, for preventing disconnects during large transfers, it's often necessary.
Restart the SSH service: After saving
sshd_config, you must restart the SSH daemon for changes to take effect:sudo systemctl restart sshd
4. Optimize Git Pack Settings (Client and Server)
For extremely large repositories or those with deep histories, Git's packing process itself can become resource-intensive. Adjusting these settings can reduce memory usage and potentially prevent timeouts.
pack.windowMemory: This limits the amount of memory Git uses when searching for delta candidates during packing. Lowering this can reduce peak memory usage but might result in a larger packfile.- Client-side:
git config --global pack.windowMemory 128m # Example: 128 MB - Server-side (if Git server is doing the packing, e.g., on
git clone/git fetch):git config --global pack.windowMemory 128m
- Client-side:
pack.depth: This controls how far back Git looks for delta compression. A smaller depth results in faster packing but a potentially larger packfile. For pushes, this usually applies to the client, but the server's configuration might influence fetches/clones.- Client-side:
git config --global pack.depth 50 # Default is 250, try lower
- Client-side:
These settings might trade off packfile size and network transfer time for reduced memory usage and faster packing. Experiment to find a balance.
5. Verify Server Resources & Limits
Resource exhaustion on the Git server can cause processes to fail, indirectly leading to a SIGPIPE on the client.
Check Disk Space: Ensure the server has ample disk space for temporary files and the repository itself.
df -hCheck Memory Usage: Monitor memory usage during the push operation.
pack-objectscan be a memory hog. If the server runs out of RAM, the Linux OOM killer might terminate processes.free -hYou can also check
dmesgfor OOM killer messages:dmesg | grep -i oom-killerCheck
ulimitsettings: Ensure the user account running the Git server processes (orsshdprocesses) doesn't have restrictiveulimitsettings for open files, memory, or CPU time. These are typically defined in/etc/security/limits.confor inherited from systemd service configurations.
6. Network Check & MTU
Intermittent network issues, packet loss, or MTU mismatches can also cause connection breaks.
Ping and Traceroute: From the client, ping the Git server to check for general connectivity and latency. Use
mtrfor more detailed path analysis.ping -c 10 your.git.server.com sudo apt install mtr mtr -rw your.git.server.comMTU (Maximum Transmission Unit): While less common, an MTU mismatch along the network path can cause packet fragmentation and reassembly issues, leading to connection instability. You might need to adjust the MTU on your network interface, but this should only be done if other network diagnostics strongly suggest it.
- Check current MTU:
ip link show eth0(replaceeth0with your interface) - Test MTU path (example):
ping -M do -s 1472 your.git.server.com(1472 bytes + 28 bytes IP/ICMP header = 1500 total, for standard Ethernet).
- Check current MTU:
7. Alternative: Use git bundle for Massive One-Off Transfers
For exceptionally large repositories, especially when migrating or seeding, git bundle can be a more robust method as it doesn't rely on a live streaming connection for the entire transfer.
On the source machine (client): Create a bundle file containing all branches or specific refs.
cd /path/to/source/repo git bundle create repo.bundle --allTransfer the bundle file: Use
scp,rsync, or another reliable file transfer method to moverepo.bundleto the target server.scp repo.bundle [email protected]:/tmp/On the target machine (server): Initialize a new repository and unbundle the contents.
cd /path/to/destination/on/server git init --bare new-repo.git cd new-repo.git git bundle unbundle /tmp/repo.bundleAlternatively, to clone directly from a bundle:
git clone /tmp/repo.bundle /path/to/destination/repo
By systematically working through these solutions, you should be able to identify and resolve the underlying cause of the "pack-objects died of signal 13 pipe break" error during your large Git pushes.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.