Troubleshooting Nginx 502 Bad Gateway with php-fpm Unix Socket on Windows WSL2 Ubuntu

Resolve Nginx 502 Bad Gateway errors on WSL2 Ubuntu when using php-fpm with a Unix socket. Debug common config, permission, and service issues.


Resolve Nginx 502 Bad Gateway errors on WSL2 Ubuntu when using php-fpm with a Unix socket. Debug common config, permission, and service issues.

A 502 Bad Gateway error from Nginx typically indicates that Nginx, acting as a reverse proxy, failed to get a valid response from the upstream server – in this case, PHP-FPM. When working within a Windows Subsystem for Linux 2 (WSL2) Ubuntu environment, using a Unix socket for Nginx-PHP-FPM communication, several specific factors can contribute to this common yet frustrating error. This guide will walk you through diagnosing and resolving the issue.

Symptom & Error Signature

When you attempt to access your PHP-powered website in a browser, you will see a generic "502 Bad Gateway" message.

<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>

The most crucial information for diagnosis, however, is found in your Nginx error logs. On Ubuntu, these are typically located at /var/log/nginx/error.log. You'll likely see entries similar to these:

2023/10/27 10:35:12 [crit] 1234#1234: *5 connect() to unix:/var/run/php/php8.2-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: your_domain.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.2-fpm.sock:", host: "your_domain.com"

2023/10/27 10:35:15 [crit] 1234#1234: *6 connect() to unix:/var/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: your_domain.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.2-fpm.sock:", host: "your_domain.com"

2023/10/27 10:35:18 [error] 1234#1234: *7 connect() to unix:/var/run/php/php8.2-fpm.sock failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: your_domain.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.2-fpm.sock:", host: "your_domain.com"

Root Cause Analysis

A 502 Bad Gateway with PHP-FPM via a Unix socket points to a communication breakdown between Nginx and the PHP-FPM service. The error messages in the Nginx log provide specific clues:

  • (2: No such file or directory): This indicates that Nginx is looking for the PHP-FPM Unix socket at a specified path, but the file simply does not exist. This is usually due to PHP-FPM not running, or it's configured to create the socket at a different path than Nginx expects.
  • (13: Permission denied): Nginx found the socket, but the nginx user (typically www-data) does not have the necessary read/write permissions to access it or the directory containing it.
  • (111: Connection refused): This is the most common 502 indicator. Nginx found the socket, had permissions to access it, but PHP-FPM either refused the connection (e.g., it's not listening on that socket, it's crashed, or it's overwhelmed), or the socket itself is misconfigured within PHP-FPM.

Common underlying reasons include:

  1. PHP-FPM Service Not Running: The most frequent culprit. If the php-fpm service isn't active, the Unix socket won't be created, and Nginx has nothing to connect to.
  2. Mismatched Socket Paths: The fastcgi_pass directive in your Nginx site configuration must precisely match the listen directive in your PHP-FPM pool configuration (www.conf). A minor typo can lead to a No such file or directory error.
  3. Incorrect Socket Permissions: PHP-FPM creates the Unix socket. If its listen.owner, listen.group, or listen.mode directives are restrictive, the www-data user (which Nginx runs as) may not be able to interact with the socket, leading to Permission denied.
  4. PHP-FPM Configuration Errors: Syntax errors in php-fpm.conf or a pool configuration file can prevent the service from starting or operating correctly.
  5. WSL2 Specifics: While WSL2's Ubuntu environment behaves largely like native Linux, ensure that systemd (if used for service management) is running correctly within your WSL2 instance, especially if you manually installed or configured services in older WSL versions that didn't enable systemd by default. Newer Ubuntu versions on WSL2 support systemd out-of-the-box.

Step-by-Step Resolution

Follow these steps sequentially to diagnose and resolve your Nginx 502 error.

1. Verify PHP-FPM Service Status

Start by checking if your PHP-FPM service is running. This is the most common reason for the socket not existing or refusing connections.

sudo systemctl status php8.2-fpm

Replace php8.2-fpm with your specific PHP version (e.g., php7.4-fpm, php8.1-fpm).

  • If it's active (running): Proceed to step 2.

  • If it's inactive (dead) or failed: Start it and check its logs.

    sudo systemctl start php8.2-fpm
    sudo systemctl status php8.2-fpm
    sudo journalctl -xeu php8.2-fpm # Check service specific logs for failures
    

    If it fails to start, investigate the output of journalctl for specific errors, which often point to configuration issues in PHP-FPM.

2. Check Nginx Error Logs for Specific Clues

As discussed in the "Symptom & Error Signature" section, the Nginx error log /var/log/nginx/error.log is your primary diagnostic tool.

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

While running this command, try accessing your site in the browser. Pay close attention to the specific error message: No such file or directory, Permission denied, or Connection refused. This will guide your next steps.

3. Inspect Nginx Site Configuration

Ensure Nginx is configured to use the correct Unix socket path. Your site's Nginx configuration file is typically in /etc/nginx/sites-available/your_domain.conf.

sudo nano /etc/nginx/sites-available/your_domain.conf

Look for a location ~ .php$ block and the fastcgi_pass directive. It should look something like this:

server {
    listen 80;
    server_name your_domain.com www.your_domain.com;
    root /var/www/html/your_site;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # <-- This path is critical
    }

    # ... other configurations
}

The path specified in fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; must exactly match the listen directive in your PHP-FPM pool configuration (Step 4).

If you make changes, always test Nginx configuration syntax and reload:

sudo nginx -t
sudo systemctl reload nginx

4. Inspect PHP-FPM Pool Configuration

Next, verify that PHP-FPM is configured to listen on the Unix socket Nginx expects and with appropriate permissions. The default pool configuration is usually at /etc/php/8.2/fpm/pool.d/www.conf.

sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Find the listen directive and verify its path. Also, check listen.owner, listen.group, and listen.mode.

; Set listen to the path where the Unix socket will be created
listen = /var/run/php/php8.2-fpm.sock

; Set permissions for the Unix socket.
; Nginx's www-data user typically needs to be able to read/write to this socket.
; 'www-data' user is usually part of 'www-data' group.
listen.owner = www-data
listen.group = www-data
listen.mode = 0660 ; 0660 gives owner/group read/write access.

Ensure the listen.owner and listen.group match the user Nginx runs as (usually www-data). The listen.mode = 0660 is generally safe and recommended for Unix sockets. If you're still having permission issues, you might temporarily try 0666 for testing, but revert to 0660 or more restrictive after diagnosing.

If you made changes, restart PHP-FPM to apply them:

sudo systemctl restart php8.2-fpm

5. Verify Socket Existence and Permissions

If PHP-FPM is running and configured correctly, the Unix socket file should exist. Check its presence and permissions.

ls -l /var/run/php/php8.2-fpm.sock

Expected output:

srw-rw---- 1 www-data www-data 0 Oct 27 10:45 /var/run/php/php8.2-fpm.sock
  • s at the beginning indicates it's a socket.
  • www-data www-data indicates the owner and group.
  • rw-rw---- (0660) indicates permissions.

Troubleshooting No such file or directory: If the file doesn't exist and PHP-FPM is running, double-check the listen path in www.conf (Step 4). There might be a typo.

Troubleshooting Permission denied:

  1. Mismatched Owner/Group: Ensure listen.owner and listen.group in www.conf are set to www-data (or whatever user Nginx runs as).
  2. Insufficient Mode: Ensure listen.mode is at least 0660.
  3. Nginx User not in Group: Less common, but ensure the www-data user is actually a member of the www-data group:
    groups www-data
    # Output should include 'www-data'
    
    If not, you might need to add it (though usually it's implicit for the user of the same name):
    sudo usermod -aG www-data www-data
    
    You would need to restart Nginx and PHP-FPM after changing user groups.

6. Check for PHP-FPM Process Issues

If PHP-FPM is running, the socket exists, and permissions seem correct, but you still get Connection refused, PHP-FPM might be overloaded or silently failing to process requests.

  • Check PHP-FPM logs:

    sudo tail -f /var/log/php8.2-fpm.log # or equivalent, check php-fpm configuration for log path
    

    Look for errors indicating memory limits, max children reached, or other critical issues.

  • Check PHP-FPM process count:

    ps aux | grep php-fpm
    

    You should see several php-fpm: pool www processes. If you see very few, or they're constantly dying and restarting, it indicates an underlying problem with your PHP application or PHP-FPM configuration.

7. WSL2 Specific Considerations (Systemd)

Modern Ubuntu versions on WSL2 (e.g., Ubuntu 22.04 LTS) include systemd support by default. If you're on an older setup or manually configured WSL, systemd might not be the default init system, potentially causing issues with services not starting or being managed correctly.

  • Verify systemd is running:

    systemctl --user list-units
    

    If this command works and shows services, systemd is likely active. If you get an error like "Failed to connect to bus", systemd might not be running.

  • Enable systemd (if not already): For older WSL2 Ubuntu installations, you might need to enable systemd. This typically involves modifying /etc/wsl.conf:

    sudo nano /etc/wsl.conf
    

    Add or modify the following:

    [boot]
    systemd=true
    

    Save the file, exit your WSL2 instance (exit), and then shut down WSL2 from PowerShell/CMD:

    wsl --shutdown
    

    Then restart your Ubuntu instance. This should enable systemd, which is crucial for reliable service management like Nginx and PHP-FPM.

After going through these steps, retest your website. One of these resolutions should bring your PHP application back online. Remember to restart Nginx and PHP-FPM after any configuration changes.