Resolve Nginx 502 Bad Gateway errors caused by PHP-FPM Unix socket permission issues on Ubuntu 22.04 LTS by correcting user, group, and listen mode configurations.
When deploying or managing web applications on an Ubuntu 22.04 LTS server, it's common to encounter the dreaded "502 Bad Gateway" error. Often, this indicates a communication breakdown between Nginx, your web server, and PHP-FPM, the FastCGI Process Manager that executes your PHP code. A frequent culprit is a permission denied error when Nginx attempts to connect to the PHP-FPM Unix socket, typically stemming from a mismatch in user and group permissions.
This guide will walk you through diagnosing and resolving this issue by ensuring Nginx has the necessary access to the PHP-FPM socket, restoring your web application's functionality.
Symptom & Error Signature
Users attempting to access your website will typically see a "502 Bad Gateway" error page directly from Nginx. On the backend, your Nginx error logs will clearly indicate the permission issue.
Browser Output:
`
502 Bad Gateway
nginx/1.22.1
`
Nginx Error Log (/var/log/nginx/error.log or similar):
`nginx
2023/10/27 10:35:45 [crit] 12345#12345: *1 connect() to unix:/var/run/php/php8.1-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:/var/run/php/php8.1-fpm.sock:", host: "example.com"
`
The key part of this error is (13: Permission denied) while connecting to upstream. This specifically tells us that Nginx could not establish a connection to the PHP-FPM Unix socket due to insufficient permissions.
Root Cause Analysis
The "PHP-FPM socket permission denied" error arises from a security mechanism designed to prevent unauthorized processes from interacting with the PHP-FPM service. When Nginx tries to communicate with PHP-FPM via a Unix domain socket, it requires read/write access to that socket file.
Here's a breakdown of the common underlying reasons:
- Nginx User/Group Mismatch:
- * By default, Nginx on Ubuntu runs as the
www-datauser and group. - * PHP-FPM also typically runs its pools as
www-data. However, if the PHP-FPM pool is configured to run under a different user or group (e.g.,php-fpm, a custom application user, or therootuser by mistake), the socket it creates might not be accessible towww-data.
- Incorrect PHP-FPM Pool Socket Configuration (
listen.owner,listen.group,listen.mode): - * The PHP-FPM pool configuration (e.g.,
/etc/php/8.1/fpm/pool.d/www.conf) defines how the Unix socket is created. - * If
listen.ownerorlisten.groupare set to users/groups other thanwww-data, andlisten.modeis restrictive (e.g.,0600), Nginx (running aswww-data) will be denied access. - * The
listen.modedirective determines the file permissions for the socket. A common secure setting is0660, which grants read/write to the owner and group, but denies others. If the Nginx user is not part of the socket's group, this will fail.
- Parent Directory Permissions:
- * Even if the socket file itself has correct permissions, the directory containing it (e.g.,
/var/run/php/) must have appropriate permissions for the Nginx user to traverse and access the socket within. Incorrect directory permissions (e.g.,0700owned byroot) can prevent Nginx from even seeing the socket file.
- SELinux or AppArmor Interference (Less Common on Ubuntu):
- * While less frequent for this specific error on a default Ubuntu setup, security modules like SELinux (on Red Hat-based systems) or AppArmor (on Ubuntu) can enforce additional access controls that might block Nginx from connecting to the socket. This usually manifests with explicit denials in audit logs.
Step-by-Step Resolution
Follow these steps to diagnose and correct the PHP-FPM socket permission issue. We'll assume PHP 8.1 for the examples, adjust versions as needed (e.g., php8.2-fpm).
1. Verify Nginx User and PHP-FPM Socket Path
First, confirm the user Nginx is running as and the exact socket path Nginx is configured to use.
- Check Nginx User:
- Typically, Nginx runs as
www-data. You can verify this in your main Nginx configuration (/etc/nginx/nginx.conf) or by inspecting running processes.
grep "user" /etc/nginx/nginx.conf
```
Expected output:
```
user www-data;
```
If not explicitly set, Nginx defaults to the user it was started by (often `root`, then it drops privileges to `www-data`).
You can also check process ownership:
```bash
ps aux | grep nginx | grep -v grep
```
- Confirm PHP-FPM Socket Path in Nginx Configuration:
- Navigate to your Nginx site configuration (e.g.,
/etc/nginx/sites-available/example.com.conf) and locate thefastcgi_passdirective.
grep -r "fastcgi_pass" /etc/nginx/sites-enabled/
```
Example output from a config file:
```nginx
# /etc/nginx/sites-available/example.com.conf
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
```
2. Inspect PHP-FPM Pool Configuration
The most common cause is incorrect settings in the PHP-FPM pool configuration. We'll edit the www.conf file, which manages the default PHP-FPM pool.
- Open the PHP-FPM Pool Configuration:
-
`bash - sudo nano /etc/php/8.1/fpm/pool.d/www.conf
-
`
- Verify
userandgroupDirectives: - Ensure the
userandgroupdirectives match the Nginx user (www-data).
; Unix user/group of processes
; Note: The user and group specified here are used for all processes of this pool.
; This also affects the ownership of the socket if listen.owner/listen.group
; are not set, or set to '0'.
user = www-data
group = www-data
- Verify
listenDirectives (Crucial): - These directives control the ownership and permissions of the Unix socket file itself.
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on a specific port;
; 'port' - to listen on a TCP socket to all addresses on a specific port;
; '/path/to/unix/socket' - to listen on a Unix socket.
; Note: This value is in effect only when the listening domain is a Unix socket.
; The file created is owned by the user/group specified in 'listen.owner' and 'listen.group'.
; Set permissions for unix socket, if one is used. In general to make it work
; with Nginx you will want to set it to 0660 or 0666.
; listen.owner = www-data
; listen.group = www-data
; listen.mode = 0660
`
Ensure these lines are uncommented (no leading semicolon ;) and configured as follows:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
-
listen.owner = www-data: Sets the owner of the socket file towww-data. - *
listen.group = www-data: Sets the group of the socket file towww-data. - *
listen.mode = 0660: Sets the file permissions torw-rw----. This means the owner (www-data) and the group (www-data) have read and write access, while others have no access. Since Nginx runs aswww-data, it will have full access.
[!WARNING] > Do not set
listen.mode = 0777or similarly permissive modes unless absolutely necessary and you understand the security implications.0660with correct owner/group is typically secure and sufficient.
- Save and Exit:
- Save the changes (
Ctrl+O, thenEnter) and exitnano(Ctrl+X).
3. Restart PHP-FPM and Nginx
After modifying the PHP-FPM configuration, you must restart the PHP-FPM service for changes to take effect. It's also good practice to restart Nginx.
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx
[!IMPORTANT] If
systemctl restart php8.1-fpmfails, check the PHP-FPM logs for syntax errors:sudo journalctl -u php8.1-fpm -f
4. Verify Socket File Permissions
After restarting PHP-FPM, the socket file should be recreated with the new permissions. Verify its ownership and mode.
ls -l /var/run/php/php8.1-fpm.sock
Expected output (or similar, depending on PHP version):
`
srw-rw—- 1 www-data www-data 0 Oct 27 10:45 /var/run/php/php8.1-fpm.sock
`
The s at the beginning indicates it's a socket file. Crucially, the owner and group should both be www-data, and the permissions should be rw-rw----.
If the group is something other than www-data (e.g., php-fpm), you have two main options:
1. Change listen.group in www.conf to www-data (as done in Step 2, and recommended).
2. Add the www-data user to that specific group. For example, if the socket's group is php-fpm:
`bash
sudo usermod -aG php-fpm www-data
sudo systemctl restart nginx
`
Then, ensure listen.mode = 0660 is set in www.conf and restart php8.1-fpm.
5. Check Parent Directory Permissions
While less common to be the primary cause for this specific error after correcting FPM config, incorrect directory permissions for /var/run/php/ can also contribute. Ensure the Nginx user can traverse this directory.
ls -ld /var/run/php
Expected output:
`
drwxr-xr-x 2 root root 60 Oct 27 10:45 /var/run/php
`
The drwxr-xr-x (755) permissions allow root full access, and all other users (including www-data) read and execute (traverse) access. This is generally sufficient. If the permissions are more restrictive (e.g., drwx------), you might need to adjust them:
sudo chmod 755 /var/run/php
```
6. Test Your Website
After completing the steps and restarting services, try accessing your website again. The "502 Bad Gateway" error should now be resolved, and your PHP application should load correctly.
If the issue persists, review the Nginx and PHP-FPM error logs again (e.g., sudo tail -f /var/log/nginx/error.log and sudo journalctl -u php8.1-fpm -f) for any new errors or clues. There might be a different underlying problem, or a subtle configuration mistake.
Leave a Reply