Nginx + Apache File Uploads Failing: Solving ERR_CONNECTION_RESET for Files >1MB


2 views

When your uploads work flawlessly for small files but fail catastrophically at the 1MB threshold, the culprit is often a hidden configuration limit. Here's what I discovered during my troubleshooting:

# Key PHP settings that should allow large uploads
upload_max_filesize = 1000M
post_max_size = 0  # Note: 0 means unlimited in PHP
memory_limit = 512M

Many developers stop at PHP configuration, but when using Nginx as reverse proxy, we need additional checks:

# Nginx configuration needed in server block
client_max_body_size 1000M;
proxy_read_timeout 300s;
proxy_connect_timeout 300s;

Even with proper PHP and Nginx settings, Apache might be the bottleneck:

# Add to Apache configuration (httpd.conf or virtual host)
LimitRequestBody 1073741824  # 1GB limit
TimeOut 300

When logs show nothing, try these diagnostic techniques:

# Test direct upload to Apache bypassing Nginx
curl -v -F "file=@largefile.zip" http://backend-server/upload.php

# Check kernel-level limits
sysctl -a | grep net.core.wmem

Here's a working setup I've implemented across multiple servers:

# Nginx site configuration
server {
    listen 80;
    client_max_body_size 1024M;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    
    location / {
        proxy_pass http://apache_backend;
        proxy_read_timeout 300;
    }
}

# PHP configuration (php.ini)
upload_max_filesize = 1024M
post_max_size = 1025M
max_execution_time = 300
memory_limit = 512M

Use tcpdump to see where the connection actually dies:

tcpdump -i eth0 -s 0 -w upload_capture.pcap port 80
# Analyze in Wireshark for RST packets

Recently, I encountered a frustrating issue where file uploads would fail with ERR_CONNECTION_RESET in Chrome when attempting to upload files larger than 1MB, despite having proper PHP settings:

upload_max_filesize = 1000M
post_max_size = 0
memory_limit = 512M

First, I checked all the usual suspects:

  • Verified PHP settings were loaded correctly using phpinfo()
  • Confirmed the error log path was writable
  • Checked both Nginx and Apache logs

After extensive testing, I discovered the issue was with Nginx's default proxy buffering settings. Here's the configuration that solved it:

location / {
    proxy_pass http://backend;
    proxy_buffering off;
    proxy_request_buffering off;
    client_max_body_size 1000M;
    proxy_connect_timeout 300;
    proxy_send_timeout 300;
    proxy_read_timeout 300;
    send_timeout 300;
}

While we're at it, these Apache settings helped ensure smooth large file uploads:

<IfModule mod_fcgid.c>
    FcgidMaxRequestLen 1073741824
    FcgidConnectTimeout 300
    FcgidIOTimeout 300
    FcgidBusyTimeout 300
</IfModule>

To ensure PHP is properly configured, create a test script:

<?php
phpinfo();
?>

Then verify these key settings:

  • upload_max_filesize
  • post_max_size
  • memory_limit

After implementing these changes, test with a simple upload form:

<form action="upload.php" method="post" enctype="multipart/form-data">
    Select file to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload File" name="submit">
</form>

And the corresponding PHP handler:

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], "uploads/".$_FILES["fileToUpload"]["name"])) {
        echo "File uploaded successfully";
    } else {
        echo "Upload failed";
    }
}
?>