Runtimes Intermediate

Troubleshooting PHP-FPM Socket Permission Denied: Nginx User/Group Mismatch on Ubuntu 20.04 LTS

Resolve 'Permission denied' errors between Nginx and PHP-FPM on Ubuntu 20.04 LTS. This guide addresses common user and group mismatch issues preventing proper socket access.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve 'Permission denied' errors between Nginx and PHP-FPM on Ubuntu 20.04 LTS. This guide addresses common user and group mismatch issues preventing proper socket access.

When deploying or managing web applications on Ubuntu 20.04 LTS with Nginx and PHP-FPM, encountering a "502 Bad Gateway" error is a common symptom of deeper issues. One of the most frequent culprits is a permission denied error related to Nginx attempting to connect to the PHP-FPM Unix socket. This guide will walk you through diagnosing and resolving the underlying user and group mismatch that causes this critical communication breakdown.

Symptom & Error Signature

The primary symptom you'll observe is a "502 Bad Gateway" error page when accessing your PHP-powered website. While the browser only shows a generic error, the Nginx error logs provide the precise diagnostic information.

You can typically find the Nginx error logs at /var/log/nginx/error.log. The specific error signature will look similar to this:

2023/10/26 10:30:05 [crit] 12345#12345: *1 connect() to unix:/run/php/php7.4-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock:", host: "example.com"

In some cases, especially if Nginx can't even initiate the connection, you might also see:

2023/10/26 10:30:05 [error] 12345#12345: *1 upstream prematurely closed connection while reading response header from upstream, client: 192.168.1.100, server: example.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.4-fpm.sock", host: "example.com"

The key indicator is (13: Permission denied) directly following connect() to unix:/run/php/phpX.X-fpm.sock failed.

Root Cause Analysis

The "Permission denied" error indicates that the Nginx worker process, when attempting to communicate with the PHP-FPM process via its Unix domain socket, lacks the necessary read/write privileges to access that socket file.

This typically stems from one or more of the following configuration discrepancies:

  1. Nginx Process User/Group vs. PHP-FPM Socket Ownership:

    • By default, Nginx worker processes run as the www-data user and group on Ubuntu.
    • PHP-FPM, when configured to use a Unix socket, creates this socket file. The ownership (user and group) and permissions (mode) of this socket are determined by the PHP-FPM pool configuration.
    • If the Nginx user (www-data) is not the owner of the socket, and is not a member of the group that owns the socket, it will be denied access unless the mode is set to globally world-readable/writable (which is insecure and rarely recommended).
  2. Incorrect PHP-FPM Pool Configuration (listen.owner, listen.group, listen.mode):

    • These directives in your PHP-FPM pool configuration file explicitly control the Unix socket's ownership and permissions. If they are not set correctly to allow the www-data user (or group) access, the error occurs.
  3. PHP-FPM Process User/Group Mismatch (user, group):

    • The user and group directives within the PHP-FPM pool configuration determine which system user and group PHP-FPM processes run as. While not directly related to socket access for Nginx, incorrect settings here can sometimes lead to issues if the socket is created in a directory with restricted permissions that only the PHP-FPM user can write to, and Nginx needs to interact with it via its own user. However, the listen.owner/listen.group/listen.mode are the primary culprits for socket access.
  4. Socket Directory Permissions:

    • The directory containing the socket (e.g., /run/php/) must also have permissions that allow the PHP-FPM process to create the socket, and sometimes Nginx to traverse it. However, the (13: Permission denied) error typically points directly to the socket file itself, not the parent directory.

Step-by-Step Resolution

Follow these steps to diagnose and correct the user/group mismatch and restore communication between Nginx and PHP-FPM.

1. Verify Nginx Process User

First, confirm the user and group under which Nginx worker processes are running.

ps aux | grep nginx | grep worker

You should see output similar to:

root      12345  0.0  0.0 123400  4000 ?        Ss   Oct25   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data  12346  0.0  0.0 123896  6000 ?        S    Oct25   0:00 nginx: worker process
www-data  12347  0.0  0.0 123896  6000 ?        S    Oct25   0:00 nginx: worker process

This confirms Nginx worker processes run as the www-data user and www-data group (as /etc/nginx/nginx.conf typically specifies user www-data;). This is the user/group that needs read/write access to the PHP-FPM socket.

2. Identify the PHP-FPM Socket Path

Check your Nginx site configuration file (e.g., /etc/nginx/sites-available/your_site.conf) to determine the exact Unix socket path Nginx is trying to connect to. Look for fastcgi_pass unix:.

# Example Nginx site configuration snippet
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php index.html index.htm;

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock; # <-- This is the socket path
    }
    # ... other configurations
}

Make a note of the exact socket path (e.g., /run/php/php7.4-fpm.sock).

3. Inspect Current Socket Permissions (if socket exists)

If PHP-FPM is running, the socket file should exist. Use ls -l to inspect its current ownership and permissions.

ls -l /run/php/php7.4-fpm.sock

You might see something like this (which would cause the error):

srw-rw---- 1 root root 0 Oct 26 10:30 /run/php/php7.4-fpm.sock

In this example, the socket is owned by root:root, and the www-data user (and group) cannot access it.

4. Adjust PHP-FPM Pool Configuration

This is the most critical step. You need to modify the PHP-FPM pool configuration file to ensure the socket is created with the correct ownership and permissions.

The default pool configuration for PHP-FPM is usually found at /etc/php/X.X/fpm/pool.d/www.conf (replace X.X with your PHP version, e.g., 7.4).

Open the relevant .conf file using a text editor:

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

Locate the following directives and ensure they are uncommented and set as follows:

; Set listen.owner to the Nginx user
listen.owner = www-data

; Set listen.group to the Nginx group
listen.group = www-data

; Set listen.mode to allow read/write access for owner and group
listen.mode = 0660

The listen.owner and listen.group must match the user and group Nginx worker processes run as (www-data by default on Ubuntu). The listen.mode = 0660 provides read/write permissions for the owner and group, which is standard and secure. Do not use 0666 as it grants world-writable access.

While you're in the file, also verify the user and group directives that control which user/group PHP-FPM processes run as. For typical setups, these should also be www-data:

; Unix user and group of processes
user = www-data
group = www-data

Save the file and exit the text editor.

5. Restart PHP-FPM and Nginx Services

For the changes to take effect, you must restart both PHP-FPM and Nginx. Restart PHP-FPM first, then Nginx.

sudo systemctl restart php7.4-fpm
sudo systemctl restart nginx

Always replace php7.4-fpm with your specific PHP-FPM service name (e.g., php8.1-fpm). You can list available PHP-FPM services with systemctl list-units --type=service | grep php-fpm.

6. Verify Corrected Socket Permissions

After restarting PHP-FPM, the socket should be re-created with the new permissions. Check it again:

ls -l /run/php/php7.4-fpm.sock

You should now see output similar to this:

srw-rw---- 1 www-data www-data 0 Oct 26 10:45 /run/php/php7.4-fpm.sock

This indicates the socket is owned by www-data:www-data with 0660 permissions, allowing Nginx (running as www-data) full access.

7. Test Your Website

Now, try accessing your website again. The "502 Bad Gateway" error should be resolved, and your PHP application should load correctly.

8. Advanced Debugging (If Problem Persists)

If the issue still persists, consider these points:

  • AppArmor/SELinux: On Ubuntu, AppArmor is enabled by default. While less common to cause direct socket permission issues (unless you have highly customized profiles), it can restrict process interactions. Check /var/log/kern.log or dmesg | grep DENIED for any AppArmor denials related to Nginx or PHP-FPM.
  • Parent Directory Permissions: Though less likely for this specific error signature, ensure the /run/php/ directory has appropriate permissions (e.g., drwxr-xr-x root root). PHP-FPM needs to be able to write to this directory.
    ls -ld /run/php/
    
    If PHP-FPM is running as www-data and /run/php is not world-writable, this could be an issue. However, systemd usually sets this up correctly for /run/php/.

By meticulously following these steps and ensuring the Nginx user has appropriate access to the PHP-FPM Unix domain socket, you can effectively resolve the "Permission denied" error and restore your PHP-powered applications on Ubuntu 20.04 LTS.

👨‍💻

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.