Debugging Nginx 502 Bad Gateway: Fixing “upstream prematurely closed connection” with FastCGI


6 views

If you're seeing this error in your Nginx logs:

upstream prematurely closed connection while reading response header from upstream

You're not alone. This common Nginx issue occurs when your FastCGI process (PHP-FPM in most cases) crashes or times out before completing the request.

Let's examine the critical configuration parameters that often cause this issue:

location ~ \\.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  app_dev.php;
    fastcgi_param  SCRIPT_FILENAME  $request_filename;
    include        fastcgi_params;
}

Here are the most effective fixes I've found:

1. Increase Timeout Values

Add these parameters to your PHP location block:

fastcgi_read_timeout 300;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;

2. Verify PHP-FPM Configuration

Check your PHP-FPM pool configuration (typically in /etc/php-fpm.d/www.conf):

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

3. Buffer Size Adjustments

Add these to your nginx server block:

fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;

If the issue persists, try these debugging steps:

# Enable detailed logging in PHP-FPM
catch_workers_output = yes

# Check for segmentation faults
sudo tail -f /var/log/php-fpm.log

# Verify socket permissions
ls -la /var/run/php-fpm/

Here's a complete working configuration that addresses most 502 issues:

location ~ \\.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
    
    fastcgi_read_timeout 300;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
}

When working with Nginx and PHP-FPM (FastCGI), one of the most frustrating errors you might encounter is:

upstream prematurely closed connection while reading response header from upstream, 
client: 127.0.0.1, server: local.example.com, request: "GET / HTTP/1.1", 
upstream: "fastcgi://127.0.0.1:9000"

This error typically occurs when:

  • PHP-FPM process crashes or times out before completing the request
  • Nginx's proxy timeout settings are too short
  • PHP script exceeds memory limits
  • FastCGI buffer sizes are insufficient
  • SSL handshake issues between Nginx and PHP-FPM

Here's an optimized Nginx configuration that addresses these issues:

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
    
    # Critical timeout settings
    fastcgi_read_timeout 300;
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 60;
    
    # Buffer optimizations
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    
    # Error handling
    fastcgi_intercept_errors on;
}

Your PHP-FPM pool configuration (/etc/php/7.4/fpm/pool.d/www.conf) needs these adjustments:

[www]
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

; Increase these values
request_terminate_timeout = 300s
request_slowlog_timeout = 60s

When the error persists, try these diagnostic steps:

# Check PHP-FPM error logs
tail -f /var/log/php7.4-fpm.log

# Verify PHP-FPM is running
ps aux | grep php-fpm

# Test FastCGI connection directly
SCRIPT_NAME=/status SCRIPT_FILENAME=/status QUERY_STRING= REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000

If you're using HTTPS (as in the original config), ensure:

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_buffer_size 16k;

# Modern cipher suite
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384...';
ssl_prefer_server_ciphers on;

After making changes:

sudo nginx -t
sudo service nginx restart
sudo service php-fpm restart

Monitor your error logs in real-time to confirm the issue is resolved:

tail -f /var/log/nginx/error.log