Runtimes Advanced

PHP-FPM Socket Permission Denied: Nginx User/Group Mismatch on WSL2 Ubuntu

Resolve 'PHP-FPM socket permission denied' with Nginx on WSL2 Ubuntu. Learn to fix user/group mismatches and configure PHP-FPM for seamless web service.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve 'PHP-FPM socket permission denied' with Nginx on WSL2 Ubuntu. Learn to fix user/group mismatches and configure PHP-FPM for seamless web service.

Welcome to this in-depth troubleshooting guide for a common and frustrating issue faced by developers and system administrators running web services on Windows Subsystem for Linux 2 (WSL2): the "PHP-FPM socket permission denied" error when Nginx attempts to connect. This error typically manifests as a "502 Bad Gateway" response from Nginx, indicating that it could not successfully communicate with the PHP-FPM backend. While WSL2 provides a full Linux environment, understanding the interaction between Nginx and PHP-FPM, particularly regarding user and group permissions on Unix domain sockets, is crucial for a stable setup.

Symptom & Error Signature

When encountering this issue, your web browser will display a "502 Bad Gateway" error. On the server side, the most definitive indicator will be found in your Nginx error logs, typically located at /var/log/nginx/error.log.

Here's a common example of the error signature you'll find:

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

You might also see a similar message with slightly different error codes or descriptions, but the core "Permission denied" on the Unix socket is the key identifier.

Root Cause Analysis

The "Permission denied" error indicates that the Nginx worker process, despite successfully identifying the PHP-FPM socket, lacks the necessary permissions to establish a connection. This is fundamentally a Unix filesystem permission issue, exacerbated by the intricacies of user and group management within a typical web stack.

Here's a breakdown of the underlying reasons:

  1. Unix Domain Sockets: PHP-FPM, by default, communicates with Nginx via a Unix domain socket (e.g., /var/run/php/php8.2-fpm.sock). This socket acts like a file on the filesystem and, as such, is governed by standard Unix permissions (read, write, execute) for the owner, group, and others.

  2. Process Ownership:

    • PHP-FPM: The PHP-FPM master process typically runs as root, but it spawns worker processes that handle actual requests. These worker processes, and crucially the Unix socket they create, usually run under a less privileged user and group, most commonly www-data:www-data on Ubuntu systems.
    • Nginx: Similarly, the Nginx master process runs as root, but its worker processes (which initiate connections to PHP-FPM) also run as a less privileged user, again, most commonly www-data:www-data on Ubuntu.
  3. Permission Mismatch: The core problem arises when the user/group under which the Nginx worker process runs does not have sufficient permissions to write to the PHP-FPM socket. This can happen if:

    • The php-fpm pool is configured to run under a user/group different from Nginx's www-data (e.g., a specific project user).
    • The listen.owner or listen.group directives in the PHP-FPM pool configuration are not set correctly, or are omitted, leading to the socket being owned by the root user or an unexpected user/group.
    • The listen.mode for the PHP-FPM socket is too restrictive (e.g., 0600 for owner-only access), and the Nginx user is not the owner.
    • The Nginx user is part of a different primary group than the PHP-FPM socket's group, and Nginx isn't added as a supplementary member to the PHP-FPM group.
  4. WSL2 Context: While WSL2 runs a full Linux kernel and handles permissions like any native Linux system within the Ubuntu instance, initial setup or user configurations might sometimes lead to unexpected user/group IDs or permissions if not explicitly defined for web services. However, for this specific "socket permission denied" error, the root cause almost always lies in misconfigured Nginx or PHP-FPM user/group settings, not a WSL2-specific filesystem bug.

Step-by-Step Resolution

To resolve this issue, we need to ensure that the Nginx worker process has the necessary permissions to communicate with the PHP-FPM Unix socket. The most robust solution involves aligning the user and group configurations of both services.

1. Identify the Nginx User and Group

First, determine which user and group Nginx is running as. This is typically configured in /etc/nginx/nginx.conf.

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

You'll usually see an output similar to:

user www-data;

This indicates Nginx workers run as the www-data user with its primary group also being www-data.

2. Identify the PHP-FPM Socket Path and Current Permissions

Next, find the location of your PHP-FPM pool configuration file and the socket it creates. The most common pool file is www.conf, and the path to PHP-FPM varies slightly by PHP version.

# Find the PHP-FPM pool configuration file (e.g., for PHP 8.2)
sudo find /etc/php -name "www.conf"

# Example output: /etc/php/8.2/fpm/pool.d/www.conf

Once you have the path, inspect the listen directive within that configuration file to get the exact socket path:

sudo grep -E "listens*=" /etc/php/8.2/fpm/pool.d/www.conf

Example output:

listen = /var/run/php/php8.2-fpm.sock

Now, check the current permissions and ownership of that socket file. Note that this file only exists when PHP-FPM is running.

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

A problematic output might look like:

srw-rw---- 1 root root 0 Oct 27 10:30 /var/run/php/php8.2-fpm.sock

Here, the socket is owned by root:root with 0660 permissions, meaning only root and members of the root group can access it. If Nginx runs as www-data, it will be denied.

3. Adjust PHP-FPM Pool Configuration

This is the most critical step. We need to configure the PHP-FPM pool to create the socket with appropriate ownership and permissions that Nginx can access.

Open your PHP-FPM pool configuration file using a text editor (e.g., nano):

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

Locate the listen directive and ensure the following lines are uncommented and correctly set:

; Listen to a unix socket at this address
listen = /var/run/php/php8.2-fpm.sock

; Set permissions for unix socket, if one is used. In the case of a socket,
; the listen property generally defines the path to the socket file.
; These values must be set if the user/group in which PHP-FPM runs
; (often 'www-data') is different from the user/group in which Nginx runs.
; However, it's best practice to explicitly set them even if they are the same.
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

The listen.owner and listen.group should match the user and group Nginx is running as (usually www-data).

The listen.mode = 0660 setting grants read/write permissions to the owner (www-data) and the owner's group (www-data). This is a secure and standard practice, ensuring Nginx (which runs as www-data) can access the socket. Avoid 0666 (world-writable) as it is a security risk.

Save the file and exit the editor (Ctrl+X, Y, Enter for nano).

4. Verify Nginx User's Group Membership (If Necessary)

In most standard Ubuntu setups, both Nginx and PHP-FPM will run as www-data:www-data, making the listen.owner = www-data, listen.group = www-data, listen.mode = 0660 configuration sufficient.

However, if you've configured PHP-FPM to run under a different group (e.g., php-users) and Nginx's primary group is www-data, you would need to add the Nginx user to PHP-FPM's group.

To check the groups www-data belongs to:

groups www-data

If www-data is not a member of the group you've set for listen.group in PHP-FPM (and that group is not www-data), add it:

sudo usermod -aG <php-fpm-group> www-data

Replace <php-fpm-group> with the actual group name.

This step is usually not required for a typical, single-user PHP-FPM setup where both Nginx and PHP-FPM run as www-data. Only proceed if you have a specific reason for PHP-FPM to run under a different group. Modifying group memberships can sometimes require a service restart or even a system reboot for processes to fully inherit new group memberships, though Nginx restarting is usually sufficient here.

5. Restart Services

After making configuration changes, you must restart both PHP-FPM and Nginx for the changes to take effect.

sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx

Always restart PHP-FPM before Nginx, especially if you're making changes to the socket configuration. This ensures the socket is correctly created before Nginx tries to connect.

6. Verify the Fix

After restarting, check your website. The "502 Bad Gateway" error should be resolved. You can also verify by:

  • Checking Nginx error logs: Confirm no new Permission denied errors appear.
    tail -f /var/log/nginx/error.log
    
  • Checking socket permissions again:
    ls -la /var/run/php/php8.2-fpm.sock
    
    The output should now look like:
    srw-rw---- 1 www-data www-data 0 Oct 27 10:45 /var/run/php/php8.2-fpm.sock
    
    This confirms the socket is owned by www-data:www-data with 0660 permissions, allowing the Nginx worker process to connect.

By following these steps, you should successfully resolve the "PHP-FPM socket permission denied" error on your WSL2 Ubuntu environment, allowing Nginx and PHP to communicate seamlessly.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn →

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.