Back to blog
Linux & Servers August 20, 2026

How to Fix Nginx Permission Denied Upstream Socket Errors

How to Fix Nginx Permission Denied Upstream Socket Errors

When using Nginx as a reverse proxy, web requests are often forwarded to backend applications (like Gunicorn, Node.js, or PHP-FPM) using Unix sockets instead of local TCP ports. Unix sockets are faster and require less CPU overhead, but they introduce strict Linux file permission requirements.

If your permissions are misconfigured, Nginx will return an HTTP 502 Bad Gateway to your users. When you check /var/log/nginx/error.log, you will find this entry:

connect() to unix:/run/myapp/myapp.sock failed (13: Permission denied)

The error code 13 indicates that the user running the Nginx worker process cannot read or write to the socket file, or is blocked from traversing the socket's parent directories.


1. Checking Nginx Worker and Socket Owners

To resolve this issue, you must identify which user is running your Nginx worker processes. By default on Ubuntu and Debian systems, Nginx runs as www-data. On CentOS or RHEL, it runs as nginx.

Identify the active worker user with this command:

ps aux | grep nginx

Once you know the Nginx worker user, check the permissions and ownership of your Unix socket file:

ls -la /run/myapp/myapp.sock

If the socket file is owned by your deployment user and group (e.g., myapp:myapp) and has permission settings of 660 (srw-rw----), Nginx will not have permission to access it.


2. Common Socket Error Patterns

Understanding the exact error message in the Nginx logs simplifies the troubleshooting process. The table below lists the three common socket connection errors:

Nginx Log Error MessagePrimary CauseRecommended Action
13: Permission deniedThe Nginx worker user lacks read/write permissions on the socket or cannot traverse the parent folders.Audit the socket permissions (660) and parent directory access (755).
2: No such file or directoryThe socket file does not exist, or Nginx is pointed to an incorrect directory path.Verify that the backend process is running and generating the socket file in the correct directory.
111: Connection refusedThe backend application process has stopped listening or has crashed.Restart your backend service (Gunicorn, PHP-FPM, uWSGI).

3. Resolving Traversal Blocks with Namei

A common mistake is fixing the permissions of the socket file while ignoring the parent directories. Even if the socket file has 777 permissions, Nginx cannot connect if it cannot traverse the folders leading to it.

Use the namei tool to trace path permissions from the root down to the socket file:

namei -l /run/myapp/myapp.sock

The output displays permissions for each segment:

f: /run/myapp/myapp.sock
drwxr-xr-x root  root     /
drwxr-xr-x root  root     run
drwx------ myapp myapp    myapp
s????????? ?     ?        myapp.sock

In the output above, the directory /run/myapp is restricted to the myapp user (drwx------). Since Nginx runs as www-data, it cannot access the folder. Fix this by allowing traversal access to group members:

sudo chmod 755 /run/myapp

4. Persisting Permissions with Systemd

If you manually run chmod 660 on the socket file, the permissions will reset the next time your application restarts. To persist these configurations, update your systemd service file (e.g., /etc/systemd/system/myapp.service):

[Service]
User=myapp
Group=www-data
UMask=0007
RuntimeDirectory=myapp
RuntimeDirectoryMode=0755
ExecStart=/path/to/gunicorn --bind unix:/run/myapp/myapp.sock myapp.wsgi:application
  • Group=www-data: Runs the process under a group that Nginx can access.
  • UMask=0007: Ensures the Unix socket is created with 660 permissions, allowing the www-data group read/write access.
  • RuntimeDirectory=myapp: Creates /run/myapp/ automatically upon service start.
  • RuntimeDirectoryMode=0755: Sets directory permissions to allow Nginx traversal.

Reload and restart the services to apply changes:

sudo systemctl daemon-reload
sudo systemctl restart myapp
sudo systemctl restart nginx

5. Auditing AppArmor Restrictions

If Unix permissions are configured correctly but Nginx still logs a permission denied error, AppArmor or SELinux might be blocking the access. AppArmor profiles on Ubuntu can prevent Nginx from reading files outside of specific directories.

Run this command to check for AppArmor denials:

sudo dmesg | grep -i apparmor

If you find active denials relating to your socket path, edit the Nginx AppArmor profile configuration to allow read/write access to /run/myapp/*.


6. Proactive Outage Monitoring with Pingzo

Upstream socket permission failures are common during automated deployments. When permission blocks occur, your backend returns a 502 Bad Gateway, but local server checkers might report that the process is running.

Pingzo helps prevent these silent failures by verifying your endpoints from external global validation nodes:

  • Real User Simulation: Pingzo attempts to load your application pages, verifying that the Nginx proxy and Unix sockets are working.
  • Instant Alerts: If a permission error triggers a 502 error, Pingzo routes a critical alert to your team via WhatsApp.
  • Response Telemetry: Identify latency spikes and connection drops caused by queue congestion on the Unix socket before they affect your users.
Try Pingzo Free

Know before your users do

Connect official WhatsApp notification channels, Discord webhooks, Telegram bots, and public status pages. Start in 30 seconds.

Create Free Monitor