sfw/fix
502 (13: Permission denied) high

502 Bad Gateway: connect() to unix:php-fpm.sock failed (13: Permission denied)

Nginx or Apache can't open the PHP-FPM Unix socket because the socket's ownership or mode shuts out the web server user.

What you see

connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied)
while connecting to upstream, AH02454

What’s actually happening

Every PHP request returns 502 Bad Gateway while static files still serve fine. The web server error log points at the socket path and errno 13. PHP-FPM itself is running and healthy — the breakdown is purely the permission handshake on the socket file. It typically starts right after a config change, a PHP version upgrade, or an SELinux/AppArmor update.

Common causes

  • listen.owner / listen.group / listen.mode in the FPM pool don't match the web server user (www-data vs nginx)
  • The socket sits in a directory the web server user can't traverse (e.g. /root or a 700 parent dir)
  • Nginx user directive and FPM pool owner drifted apart after a distro upgrade
  • SELinux denies the connection — `httpd_can_network_connect`/socket context is wrong
  • A leftover socket from an old PHP version with stale ownership after upgrading 7.4 to 8.2

How to fix it

  1. Match the socket owner to the web server userFind your web user (`ps aux | grep nginx` or `grep ^user /etc/nginx/nginx.conf`). In the pool file (/etc/php/8.2/fpm/pool.d/www.conf) set `listen.owner = www-data`, `listen.group = www-data`, `listen.mode = 0660`. Restart: `systemctl restart php8.2-fpm`.
  2. Confirm the path and check it from the web user's shoes`ls -l /run/php/php8.2-fpm.sock` and verify nginx's fastcgi_pass points at the exact same path. Test traversal: `sudo -u www-data test -r /run/php/php8.2-fpm.sock && echo OK`. If that fails, a parent directory's permissions are the culprit.
  3. Check SELinux / AppArmorOn RHEL/CentOS run `setenforce 0` briefly — if the 502 clears, SELinux is the cause. Fix it properly with `setsebool -P httpd_can_network_connect 1` and restore context via `restorecon -Rv /run/php`. On Ubuntu inspect `dmesg | grep apparmor` for DENIED lines.
  4. Clear stale sockets after a PHP upgradeAfter upgrading PHP, the old socket can linger with wrong ownership. Stop FPM, `rm /run/php/php7.4-fpm.sock`, point your fastcgi_pass at the new php8.2 socket, and restart both services.

Stop it recurring

Pin the FPM pool's listen.owner/listen.group to the exact web server user in config management so a package upgrade can't silently change it.

Related errors