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";
}
}
?>