Nginx Worker Process Permissions Denied Opening Unix Socket on WSL2 Ubuntu

Troubleshoot 'permissions denied' when Nginx worker processes fail to open a Unix socket on Windows WSL2 Ubuntu. Fix PHP-FPM and directory permissions.


Troubleshoot 'permissions denied' when Nginx worker processes fail to open a Unix socket on Windows WSL2 Ubuntu. Fix PHP-FPM and directory permissions.

When running Nginx on Windows Subsystem for Linux 2 (WSL2) with an Ubuntu distribution, you might encounter a frustrating "permissions denied" error related to Unix sockets. This typically prevents Nginx from communicating with backend services like PHP-FPM, leading to "502 Bad Gateway" errors in your browser or Nginx failing to start altogether. This guide will walk you through diagnosing and resolving this common issue, focusing on the correct user and directory permissions required for seamless operation.

Symptom & Error Signature

The most common symptom is your web application displaying a "502 Bad Gateway" error in the browser, or Nginx failing to start/reload with explicit permission errors in its logs.

You will typically find error messages similar to these in your Nginx error log (commonly /var/log/nginx/error.log) or when checking Nginx's status or configuration:

# Check Nginx status
sudo systemctl status nginx.service

# Expected output snippets:
# nginx.service: Failed with result 'exit-code'.
# Failed to start A high performance web server and a reverse proxy server.

# Check Nginx error log
sudo tail -f /var/log/nginx/error.log

# Expected error messages in the log:
# 2026/08/06 10:30:05 [crit] 12345#12345: *1 connect() to unix:/run/php/php8.1-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:/run/php/php8.1-fpm.sock:", host: "localhost"
# 2026/08/06 10:30:05 [error] 12345#12345: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
# 2026/08/06 10:30:05 [crit] 12346#12346: *2 connect() to unix:/var/run/my-app.sock failed (13: Permission denied)

The key part of the error is connect() to unix:... failed (13: Permission denied). This explicitly indicates that the Nginx worker process, when attempting to establish a connection to a Unix domain socket, was denied access by the operating system due to insufficient permissions.

Root Cause Analysis

This error almost universally stems from a mismatch in user or group permissions between the Nginx worker processes and the Unix domain socket they are trying to access. Here's a breakdown of the underlying reasons:

  1. Nginx User Permissions: By default, Nginx worker processes run as the www-data user and group on Ubuntu/Debian systems. This user needs read and write access to the Unix socket file and execute permissions on all parent directories leading to that socket.
  2. PHP-FPM Socket Creation: PHP-FPM, which is typically the service Nginx connects to via a Unix socket, creates this socket file. The permissions of this socket are determined by PHP-FPM's configuration, specifically listen.owner, listen.group, and listen.mode directives in its pool configuration (e.g., /etc/php/8.1/fpm/pool.d/www.conf). If PHP-FPM creates the socket with permissions that don't allow the www-data user to access it, Nginx will fail to connect.
  3. Directory Permissions: Even if the socket file itself has correct permissions, Nginx still needs execute permission on the directory containing the socket. For example, if the socket is /run/php/php8.1-fpm.sock, the www-data user needs execute permission on /run and /run/php.
  4. WSL2 Nuances (Less Common for Sockets): While less common for /run or /var/run directories (which are typically native Linux filesystems within WSL2), permission issues can arise if you store configuration files or try to place sockets on a mounted Windows filesystem (/mnt/c/). Windows ACLs translate imperfectly to POSIX permissions, and native chmod/chown operations might not behave as expected on those mounts. For Unix sockets, always ensure they reside on the Linux filesystem.

In most scenarios, the Nginx www-data user is simply not permitted to read from or write to the PHP-FPM socket because PHP-FPM created it with restrictive permissions, or the socket's parent directory lacks appropriate permissions for www-data.

Step-by-Step Resolution

Follow these steps to diagnose and resolve the "permissions denied opening unix socket" error.

1. Verify Nginx Configuration User

First, confirm which user Nginx is configured to run as. This is crucial for setting correct permissions.

  1. Check nginx.conf: Look for the user directive at the top of your main Nginx configuration file.

    grep "user" /etc/nginx/nginx.conf
    

    You should typically see:

    user www-data;
    

    If it's different (e.g., user nginx; or your personal user), make a note of it. For consistency, www-data is highly recommended on Debian/Ubuntu systems.

    If you change the user directive, remember to restart Nginx later.

2. Identify the Unix Socket Path

Next, find the exact path of the Unix socket that Nginx is trying to connect to. This path is specified in your Nginx server block configuration.

  1. Locate fastcgi_pass or proxy_pass directives: Check your Nginx site configuration files (typically in /etc/nginx/sites-available/). Look for fastcgi_pass directives pointing to a unix: socket, or proxy_pass directives similarly configured.

    grep -r "fastcgi_pass unix:" /etc/nginx/sites-available/
    grep -r "proxy_pass http://unix:" /etc/nginx/sites-available/
    

    Common examples include:

    • fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    • fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    • proxy_pass http://unix:/var/run/my-app.sock;

    Let's assume the socket path is /run/php/php8.1-fpm.sock for the rest of this guide, as this is the most common scenario with PHP-FPM.

3. Adjust PHP-FPM Socket Permissions

This is the most frequent cause and solution for this error. You need to ensure the PHP-FPM socket is created with permissions allowing the Nginx user (www-data) to access it.

  1. Edit PHP-FPM Pool Configuration: Open the PHP-FPM pool configuration file. For default setups, this is usually /etc/php/X.X/fpm/pool.d/www.conf (replace X.X with your PHP version, e.g., 8.1).

    sudo nano /etc/php/8.1/fpm/pool.d/www.conf
    
  2. Modify listen directives: Locate the listen.owner, listen.group, and listen.mode directives. Ensure they are set as follows:

    ; Set owner, group and mode for the listening socket.
    ; Default values are www-data, www-data and 0660
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660
    
    • listen.owner = www-data: This ensures the socket file is owned by the www-data user (the Nginx user).
    • listen.group = www-data: This ensures the socket file is associated with the www-data group.
    • listen.mode = 0660: This grants read/write permissions to the owner (www-data) and the group (www-data), effectively allowing Nginx to connect.

    If these lines are commented out with a semicolon (;), uncomment them by removing the semicolon at the beginning of the line.

  3. Save and Exit: Save the changes (Ctrl+O, then Enter) and exit nano (Ctrl+X).

  4. Restart PHP-FPM: Apply the changes by restarting the PHP-FPM service.

    sudo systemctl restart php8.1-fpm.service
    

    (Adjust php8.1-fpm.service to your specific PHP version).

  5. Verify Socket Permissions (Optional but Recommended): After restarting PHP-FPM, you can check the actual permissions of the created socket:

    ls -la /run/php/php8.1-fpm.sock
    

    You should see something like:

    srw-rw---- 1 www-data www-data 0 Aug  6 10:45 /run/php/php8.1-fpm.sock
    

    The srw-rw---- indicates a socket file (s) with read/write for owner and group, and www-data www-data confirms the correct ownership.

4. Verify Directory Permissions for the Socket Path

Even with correct socket permissions, Nginx needs execute permissions on the directories leading to the socket. For /run/php/php8.1-fpm.sock, this means checking /run and /run/php.

  1. Check Parent Directory Permissions:

    ls -lad /run/php/
    ls -lad /run/
    

    You should see execute permissions (x) for "others" or ensure the www-data user/group has appropriate access. For /run/php, typical permissions might be drwxr-xr-x or drwxrwx--- if owned by root:www-data. For /run, it's usually drwxr-xr-x.

  2. Adjust Directory Permissions (if necessary): If the www-data user or group does not have execute (x) permission on these directories, you might need to adjust them. This is less common for standard /run/php setups as they're usually managed by systemd-tmpfiles with appropriate defaults, but can be an issue for custom socket paths.

    If, for example, your socket was in /var/run/my-app/app.sock, and my-app was created with restrictive permissions:

    # Ensure www-data can traverse /var/run/my-app/
    sudo chown root:www-data /var/run/my-app/
    sudo chmod 775 /var/run/my-app/ # Grants rwx to owner and group, rx to others
    

    Avoid using chmod 777 on directories or files. It grants global read, write, and execute permissions, which is a significant security risk. Always use the least privilege necessary.

5. Confirm Nginx Service Status and Restart

After making the necessary changes, restart Nginx to ensure it picks up the new permissions and can connect to the socket.

  1. Test Nginx Configuration: It's good practice to test your Nginx configuration for syntax errors before restarting.

    sudo nginx -t
    

    You should see:

    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
  2. Restart Nginx:

    sudo systemctl restart nginx.service
    
  3. Check Nginx Status: Confirm that Nginx is running without errors.

    sudo systemctl status nginx.service
    

    The output should show Active: active (running) and no related errors in the logs.

6. Troubleshoot WSL2 Specifics (Advanced)

While usually not the primary cause for Unix socket permission issues on /run or /var/run (which are internal Linux filesystems), here are a few WSL2 considerations:

  • File Locations: Always ensure your Nginx configuration files, PHP-FPM configuration, and crucially, your Unix socket files reside entirely within the WSL2 Linux filesystem (e.g., /etc/, /var/run/, /home/). Do not place them on mounted Windows drives like /mnt/c/, as permission handling there is different and can lead to unexpected behavior.
  • Case Sensitivity: Linux filesystems are case-sensitive. Double-check all paths in your Nginx and PHP-FPM configurations for exact case matching.
  • Reboot WSL2: In rare cases, if systemd or temporary file systems are acting up, a full restart of your WSL2 distribution might resolve transient issues. Close all WSL2 terminal windows and then in a PowerShell or Command Prompt, run:
    wsl --shutdown
    
    Then, reopen your WSL2 distribution.

By carefully following these steps, you should successfully resolve the "Nginx worker process permissions denied opening unix socket" error on your WSL2 Ubuntu environment.