Git & CI/CD Advanced

Troubleshooting Git Error: pack-objects died of signal 13 pipe break during large push on Debian 12

Resolve 'git pack-objects died of signal 13 pipe break' on Debian 12 Bookworm. This guide covers timeouts, resource limits, and large Git push failures for expert sysadmins.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve 'git pack-objects died of signal 13 pipe break' on Debian 12 Bookworm. This guide covers timeouts, resource limits, and large Git push failures for expert sysadmins.

Introduction

As an experienced Systems Administrator, encountering the git error: pack-objects died of signal 13 during a large git push operation can be a frustrating and often misleading problem. This specific error, particularly when coupled with "pipe break," indicates that the pack-objects process on your client machine (responsible for compressing and packaging your Git objects) attempted to write data to a pipe, but the receiving end of that pipe closed prematurely. This premature closure is almost invariably due to an issue on the remote Git server, commonly related to timeouts or resource exhaustion.

This guide provides a highly technical, accurate, and step-by-step approach to diagnose and resolve this issue on a Debian 12 Bookworm server environment, leveraging common hosting stacks like Nginx and Systemd.

Symptom & Error Signature

When attempting a git push (especially with a large number of changes, new files, or a significant history rewrite), the operation will fail after some progress, displaying an error similar to the following in your terminal:

Enumerating objects: 123456, done.
Counting objects: 100% (123456/123456), done.
Delta compression using up to 16 threads
Compressing objects: 100% (45678/45678), done.
Writing objects: 100% (123456/123456), 2.50 GiB | 1.23 MiB/s, done.
Total 123456 (delta 98765), reused 123456 (delta 98765), pack-reused 0
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Payload Too Large
fatal: the remote end hung up unexpectedly
fatal: the remote end hung up unexpectedly
error: pack-objects died of signal 13

Alternatively, if pushing via SSH:

Counting objects: 123456, done.
Delta compression using up to 16 threads
Compressing objects: 100% (45678/45678), done.
Writing objects: 100% (123456/123456), 2.50 GiB | 1.23 MiB/s, done.
Total 123456 (delta 98765), reused 123456 (delta 98765), pack-reused 0
remote: fatal: pack-objects died of signal 13
remote: fatal: The remote end hung up unexpectedly
error: remote unpack failed: unpack-objects abnormal exit
To [email protected]:/path/to/repo.git
 ! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to 'ssh://[email protected]/path/to/repo.git'

The key message here is error: pack-objects died of signal 13. Signal 13 is SIGPIPE, indicating a broken pipe.

Root Cause Analysis

The error pack-objects died of signal 13 occurs when the git pack-objects process on your local machine attempts to write the compressed pack data to a network pipe, but the reading end of that pipe on the remote server has unexpectedly closed. This premature closure is generally indicative of one or more of the following underlying issues on the remote Git server:

  1. Server-Side Timeouts:

    • Web Server (Nginx, Apache) Timeouts: If you are pushing via HTTP/HTTPS, the web server acting as a reverse proxy for Git (e.g., git-http-backend via FastCGI/CGI) might terminate the connection due to its proxy_read_timeout, proxy_send_timeout, fastcgi_read_timeout, or similar directives being too short for a large push. A HTTP 413 Payload Too Large often accompanies this via HTTP.
    • SSH Daemon (sshd) Timeouts: If pushing via SSH, the sshd process might terminate the connection due to ClientAliveInterval or ClientAliveCountMax being too restrictive, especially during periods of inactivity within the large data transfer.
    • Git Server-Side Process Timeouts: Even the git-receive-pack process itself, or any Git hooks it invokes, might encounter internal timeouts or resource limits configured within Git or the OS.
  2. Server-Side Resource Exhaustion:

    • Memory Exhaustion: Processing large pack files on the server requires significant RAM. If the server runs out of memory while receiving, unpacking, or processing the Git pack, the git-receive-pack or unpack-objects process may be killed by the Linux OOM (Out Of Memory) killer, leading to the pipe being closed.
    • Disk Space Exhaustion: Although less common for SIGPIPE, if the server runs out of disk space during the unpacking process, it can cause the receiving process to crash.
    • CPU Exhaustion: Sustained high CPU load can lead to processes timing out or becoming unresponsive, especially when Delta compression is heavily involved.
  3. System-Wide Process Limits (ulimit):

    • The user or service under which Git operations run on the server (e.g., git user, www-data for HTTP) may have low ulimit settings for nproc (number of processes) or nofile (number of open files), which could be exceeded during complex Git operations.
  4. Network Instability:

    • While SIGPIPE directly points to a process closing the pipe, underlying intermittent network connectivity issues can trigger server-side timeouts or lead to partial data transfers that eventually cause the server process to give up.

Step-by-Step Resolution

To resolve the "pack-objects died of signal 13 pipe break" error on your Debian 12 Bookworm server, we'll systematically address potential timeout and resource limitations.

1. Analyze Server-Side Logs

Before making any changes, check the server's logs for clues.

  • System Logs: journalctl -u sshd, journalctl -u nginx, journalctl -u apache2, dmesg -T | grep -i oom
  • Git Specific Logs: If your Git server implementation (e.g., GitLab, Gitea) provides specific logs, check those.

2. Increase Client-Side http.postBuffer (for HTTP/HTTPS pushes)

If you're using HTTP/HTTPS for your Git remote, the client-side http.postBuffer setting dictates the maximum size of the HTTP POST buffer used when sending data. If your pack file is larger than this, it can lead to issues, though SIGPIPE usually points server-side. It's a good first step to ensure the client isn't bottlenecking.

# Check current setting (defaults to 1MB)
git config --global http.postBuffer

# Increase it significantly, e.g., to 500MB (524288000 bytes)
git config --global http.postBuffer 524288000

This command sets the postBuffer globally for the current user. If you prefer it per-repository, omit --global and run it inside the repository.

3. Adjust Server-Side Web Server Timeouts (for HTTP/HTTPS pushes)

If your Git repository is served via HTTP/HTTPS using Nginx or Apache, you need to increase the timeout values for large data transfers.

For Nginx:

Edit your Nginx configuration file, typically found in /etc/nginx/nginx.conf or /etc/nginx/sites-available/your-git-site.conf. Locate the location block handling Git and add or adjust the following directives:

# /etc/nginx/sites-available/your-git-site.conf
server {
    listen 80;
    server_name yourserver.com;

    # Increase body size limit for large packs
    client_max_body_size 0; # Allows unlimited body size, use with caution or a large specific value
    
    location /your-git-repo.git {
        # ... your existing Git setup (e.g., fastcgi_pass or proxy_pass) ...
        
        # Adjust proxy/fastcgi timeouts for large Git operations
        proxy_read_timeout 600s;  # 10 minutes
        proxy_send_timeout 600s;  # 10 minutes
        fastcgi_read_timeout 600s; # If using fastcgi_pass
        fastcgi_send_timeout 600s; # If using fastcgi_pass
        
        # If you were seeing HTTP 413, client_max_body_size is critical
        # client_max_body_size 1000M; # Example: 1GB, or '0' for unlimited
    }
}

Setting client_max_body_size 0 allows infinitely large requests. While this fixes the issue, consider a large, specific value like 2000M (2GB) for better resource control.

After editing, test the Nginx configuration and reload the service:

sudo nginx -t
sudo systemctl reload nginx
For Apache (if applicable):

Edit your Apache configuration file, typically in /etc/apache2/sites-available/your-git-site.conf.

# /etc/apache2/sites-available/your-git-site.conf
<VirtualHost *:80>
    ServerName yourserver.com

    # Increase timeout for long-running processes
    Timeout 600

    # Ensure large body sizes are allowed
    LimitRequestBody 0 # Unlimited body size, use with caution or a large specific value
    
    # Example for git-http-backend
    SetEnv GIT_HTTP_EXPORT_ALL
    ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

    <Location /git>
        # Auth directives etc.
        # LimitRequestBody 1073741824 # Example: 1GB, or '0' for unlimited
    </Location>
</VirtualHost>

After editing, test the Apache configuration and reload the service:

sudo apache2ctl configtest
sudo systemctl reload apache2

4. Adjust Server-Side SSH Daemon Timeouts (for SSH pushes)

If you're pushing via SSH, modify the SSH daemon's configuration file /etc/ssh/sshd_config on the server. These settings keep the connection alive even during periods of low data transfer.

# /etc/ssh/sshd_config
ClientAliveInterval 120    # Send a null packet to the client every 120 seconds
ClientAliveCountMax 5      # Allow 5 intervals without client response before disconnecting

This configuration means SSH will send a keep-alive message every 2 minutes. If the client doesn't respond after 5 such messages (total 10 minutes), the connection will be dropped. Adjust ClientAliveInterval to a smaller value if necessary for extremely sensitive networks, or increase ClientAliveCountMax for longer tolerance.

Always restart the SSH service after modifying sshd_config. Be cautious when changing SSH configurations as incorrect settings can lock you out of your server. Always test in a non-production environment first if possible, or ensure you have console access.

sudo systemctl restart sshd

5. Increase Server-Side Git Configuration Limits

Git itself has internal configuration limits that might affect how it handles large packs. These are often set per-repository or globally on the server.

# On the remote Git server, navigate to the bare repository or
# set these globally for the git user or system-wide.
# For a bare repository: cd /path/to/repo.git
# For global config: (as the user running Git or root) git config --global ...

# Set pack.windowMemory: max memory in bytes for window memory used by "git pack-objects"
# A large value helps with deep histories. Default is 256MB. Try 1GB or 2GB.
git config pack.windowMemory 2g

# Set pack.packSizeLimit: max size of a single pack file. Default is 0 (unlimited).
# If you hit issues with very large pack files, setting a limit might force Git to
# create multiple smaller packs. However, '0' is usually desired.
git config pack.packSizeLimit 0

# Increase pack.threads to utilize more CPU cores during packing/unpacking
# Default is often 0 (use system default/heuristics) or 1.
git config pack.threads 4 # Adjust based on available CPU cores

These settings might need to be applied in the global Git configuration for the user under which git-receive-pack runs (e.g., the git user for SSH access, or www-data for HTTP if Git is run directly by the web server user). git config --system can set these globally for all users.

6. Increase Server-Side System Limits (ulimit)

The user account running Git operations on the server might be hitting system ulimit restrictions. This is particularly relevant for memory-intensive operations.

Edit /etc/security/limits.conf. Add (or modify) entries for the user (git or www-data) that executes Git processes.

# /etc/security/limits.conf
# <domain>      <type>  <item>         <value>
git             soft    nofile         65536    # Max open files
git             hard    nofile         65536
git             soft    nproc          4096     # Max number of processes
git             hard    nproc          4096
www-data        soft    nofile         65536
www-data        hard    nofile         65536
www-data        soft    nproc          4096
www-data        hard    nproc          4096

Changes to limits.conf usually require the user to log out and log back in, or a full system reboot, for them to take effect. For service users (like www-data), restarting the associated service (Nginx/Apache) might be sufficient.

If Git is run via a systemd service (e.g., GitLab, Gitea), you might need to adjust limits within the .service unit file directly for the specific service.

# Example for a systemd service file (e.g., /etc/systemd/system/gitea.service)
[Service]
...
LimitNOFILE=65536
LimitNPROC=4096
...

# After modifying, reload systemd and restart the service
sudo systemctl daemon-reload
sudo systemctl restart gitea.service

7. Verify Server Memory and Swap Resources

Lack of sufficient RAM is a primary killer for pack-objects on the server side.

free -h

Check Mem: and Swap: lines. If Mem is frequently exhausted and Swap is heavily utilized, this indicates a memory bottleneck. You might need to:

  • Add more RAM to your server.
  • Increase swap space.
  • Optimize other services running on the server to consume less memory.

8. Ensure Sufficient Disk Space

While less direct, running out of disk space during the unpacking phase can cause processes to crash.

df -h

Ensure the partition where your Git repositories reside has ample free space.

9. Update Git on Both Client and Server

Outdated Git versions can sometimes have bugs or less efficient packing algorithms that are triggered by large pushes. Ensure you are running a recent stable version.

# On both client and server
git --version

To update Git on Debian 12:

sudo apt update
sudo apt install git

10. Consider Partial Pushes or Git Bundles (Advanced)

If your repository is exceptionally large or has a very deep history, and all other measures fail, consider:

  • Pushing in smaller increments: If you have a branch with many commits, try pushing smaller sets of commits. This might be difficult if the issue is with a single massive commit.

  • git bundle: For truly massive transfers or initial setup of huge repositories, git bundle can be more robust. It creates a single file containing all Git objects, which can then be transferred via scp or rsync and unbundled.

    # On the client, to create a bundle of the entire repository
    git bundle create repo.bundle --all
    
    # Transfer repo.bundle to the server via scp
    
    # On the server, clone from the bundle
    git clone repo.bundle my-new-repo
    
    # Or to pull changes from a bundle into an existing repository
    git fetch repo.bundle master
    

By systematically addressing these server-side configurations and resource limitations, you should be able to resolve the pack-objects died of signal 13 pipe break error during large Git pushes on your Debian 12 Bookworm server.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn →

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

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.