Debugging Nginx 500 Internal Server Errors: PHP Error Logging Configuration Guide


2 views

When your Nginx server returns 500 errors for specific PHP scripts while others work fine, the problem typically lies in PHP-FPM error handling rather than Nginx configuration itself. The key observation here is that while Nginx's error.log only shows basic server errors (like missing favicon.ico), it's not capturing the actual PHP errors causing the 500 responses.

First, verify your PHP-FPM configuration. Here's what you need to check in your php-fpm pool configuration (typically at /etc/php/{version}/fpm/pool.d/www.conf):

; Ensure these settings are properly configured
catch_workers_output = yes
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on

Modify your Nginx PHP location block to properly handle errors:

location ~ \\.php$ {
    fastcgi_pass unix:/tmp/phpfpm.sock;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include fastcgi_params;
    
    # Additional error handling parameters
    fastcgi_intercept_errors on;
    fastcgi_param PHP_VALUE "error_log=/home/whitey/sites/localhost/logs/php_errors.log";
    fastcgi_param PHP_ADMIN_VALUE "log_errors=On";
}

Create a test PHP file with intentional errors:

<?php
// test_error.php
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/home/whitey/sites/localhost/logs/php_errors.log');

// Generate different error types
$undefined->method(); // Fatal error
include 'non_existent_file.php'; // Warning
echo $undefined_variable; // Notice

Case 1: Permissions issues with error log files

sudo chown www-data:www-data /home/whitey/sites/localhost/logs/
sudo chmod 775 /home/whitey/sites/localhost/logs/

Case 2: PHP script execution timeout

location ~ \\.php$ {
    # ... existing config ...
    fastcgi_read_timeout 300;
}

Enable Nginx debug logging temporarily:

error_log /home/whitey/sites/localhost/logs/error.log debug;

For PHP-FPM status monitoring:

location ~ ^/(status|ping)$ {
    include fastcgi_params;
    fastcgi_pass unix:/tmp/phpfpm.sock;
    allow 127.0.0.1;
    deny all;
}
  • Verify PHP-FPM error log path exists and is writable
  • Ensure error_reporting is set to E_ALL in php.ini
  • Confirm display_errors is Off in production
  • Check SELinux/AppArmor permissions if applicable
  • Restart both Nginx and PHP-FPM after configuration changes

Nothing's more frustrating than seeing a blank 500 error page while your Nginx error logs remain suspiciously quiet. Here's how to force PHP to reveal its secrets when running under Nginx/FastCGI.

First, ensure PHP is configured to log errors properly. Add these to your php.ini or .user.ini:

display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
error_reporting = E_ALL

Your Nginx PHP location block needs these critical parameters:

location ~ \.php$ {
    fastcgi_pass unix:/tmp/phpfpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PHP_VALUE "error_log=/var/log/php_errors.log";
    fastcgi_param PHP_ADMIN_VALUE "error_reporting=E_ALL";
    include fastcgi_params;
    
    # For debugging:
    fastcgi_intercept_errors on;
    fastcgi_ignore_client_abort off;
    fastcgi_read_timeout 300;
}

The most common reason for missing logs? Permission issues. Run these commands:

sudo touch /var/log/php_errors.log
sudo chown www-data:www-data /var/log/php_errors.log
sudo chmod 664 /var/log/php_errors.log

When standard logging fails, try these nuclear options:

# Temporarily enable display errors (remove after debugging!)
fastcgi_param PHP_VALUE "display_errors=On";

# Or test with a simple script:
<?php
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    include('non_existent_file.php');
?>

Here's how we caught a memory limit error that wasn't logging:

# In nginx.conf
fastcgi_param PHP_VALUE "memory_limit=128M \n error_log=/var/log/php_debug.log";

# In the PHP script:
<?php
    ini_set('memory_limit', '64M');
    $huge_array = range(1, 10000000); // Will trigger error
?>