[nginx] Nginx 403 forbidden for all files

I have nginx installed with PHP-FPM on a CentOS 5 box, but am struggling to get it to serve any of my files - whether PHP or not.

Nginx is running as www-data:www-data, and the default "Welcome to nginx on EPEL" site (owned by root:root with 644 permissions) loads fine.

The nginx configuration file has an include directive for /etc/nginx/sites-enabled/*.conf, and I have a configuration file example.com.conf, thus:

server {
 listen 80;

 Virtual Host Name
 server_name www.example.com example.com;


 location / {
   root /home/demo/sites/example.com/public_html;
   index index.php index.htm index.html;
 }

 location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_param  PATH_INFO $fastcgi_script_name;
  fastcgi_param  SCRIPT_FILENAME  /home/demo/sites/example.com/public_html$fastcgi_script_name;
  include        fastcgi_params;
 }
}

Despite public_html being owned by www-data:www-data with 2777 file permissions, this site fails to serve any content -

 [error] 4167#0: *4 open() "/home/demo/sites/example.com/public_html/index.html" failed (13: Permission denied), client: XX.XXX.XXX.XX, server: www.example.com, request: "GET /index.html HTTP/1.1", host: "www.example.com"

I've found numerous other posts with users getting 403s from nginx, but most that I have seen involve either more complex setups with Ruby/Passenger (which in the past I've actually succeeded with) or are only receiving errors when the upstream PHP-FPM is involved, so they seem to be of little help.

Have I done something silly here?

This question is related to nginx centos http-status-code-403 php

The answer is


One permission requirement that is often overlooked is a user needs x permissions in every parent directory of a file to access that file. Check the permissions on /, /home, /home/demo, etc. for www-data x access. My guess is that /home is probably 770 and www-data can't chdir through it to get to any subdir. If it is, try chmod o+x /home (or whatever dir is denying the request).

EDIT: To easily display all the permissions on a path, you can use namei -om /path/to/check


We had the same issue, using Plesk Onyx 17. Instead of messing up with rights etc., solution was to add nginx user into psacln group, in which all the other domain owners (users) were:

usermod -aG psacln nginx

Now nginx has rights to access .htaccess or any other file necessary to properly show the content.

On the other hand, also make sure that Apache is in psaserv group, to serve static content:

usermod -aG psaserv apache

And don't forget to restart both Apache and Nginx in Plesk after! (and reload pages with Ctrl-F5)


I was facing the same issue but above solutions did not help.

So, after lot of struggle I found out that sestatus was set to enforce which blocks all the ports and by setting it to permissive all the issues were resolved.

sudo setenforce 0

Hope this helps someone like me.


If you are using PHP, make sure the index NGINX directive in the server block contains a index.php:

index index.php index.html;

For more info checkout the index directive in the official documentation.


I solved this problem by adding user settings.

in nginx.conf

worker_processes 4;
user username;

change the 'username' with linux user name.


If you still see permission denied after verifying the permissions of the parent folders, it may be SELinux restricting access.

To check if SELinux is running:

# getenforce

To disable SELinux until next reboot:

# setenforce Permissive

Restart Nginx and see if the problem persists. To allow nginx to serve your www directory (make sure you turn SELinux back on before testing this. i.e, setenforce Enforcing)

# chcon -Rt httpd_sys_content_t /path/to/www

See my answer here for more details


If you're using SELinux, just type:

sudo chcon -v -R --type=httpd_sys_content_t /path/to/www/

This will fix permission issue.


I've tried different cases and only when owner was set to nginx (chown -R nginx:nginx "/var/www/myfolder") - it started to work as expected.


I dug myself into a slight variant on this problem by mistakenly running the setfacl command. I ran:

sudo setfacl -m user:nginx:r /home/foo/bar

I abandoned this route in favor of adding nginx to the foo group, but that custom ACL was foiling nginx's attempts to access the file. I cleared it by running:

sudo setfacl -b /home/foo/bar

And then nginx was able to access the files.


I've got this error and I finally solved it with the command below.

restorecon -r /var/www/html

The issue is caused when you mv something from one place to another. It preserves the selinux context of the original when you move it, so if you untar something in /home or /tmp it gets given an selinux context that matches its location. Now you mv that to /var/www/html and it takes the context saying it belongs in /tmp or /home with it and httpd is not allowed by policy to access those files.

If you cp the files instead of mv them, the selinux context gets assigned according to the location you're copying to, not where it's coming from. Running restorecon puts the context back to its default and fixes it too.


Old question, but I had the same issue. I tried every answer above, nothing worked. What fixed it for me though was removing the domain, and adding it again. I'm using Plesk, and I installed Nginx AFTER the domain was already there.

Did a local backup to /var/www/backups first though. So I could easily copy back the files.

Strange problem....


Examples related to nginx

Kubernetes service external ip pending nginx: [emerg] "server" directive is not allowed here Disable nginx cache for JavaScript files Nginx upstream prematurely closed connection while reading response header from upstream, for large requests Nginx: Job for nginx.service failed because the control process exited How can I have same rule for two locations in NGINX config? How to verify if nginx is running or not? Find nginx version? Docker Networking - nginx: [emerg] host not found in upstream How do I rewrite URLs in a proxy response in NGINX

Examples related to centos

How to uninstall an older PHP version from centOS7 Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details pip install - locale.Error: unsupported locale setting ssh : Permission denied (publickey,gssapi-with-mic) How to change the MySQL root account password on CentOS7? Completely remove MariaDB or MySQL from CentOS 7 or RHEL 7 ffprobe or avprobe not found. Please install one How to check all versions of python installed on osx and centos Cannot find java. Please use the --jdkhome switch VirtualBox: mount.vboxsf: mounting failed with the error: No such device

Examples related to http-status-code-403

Nginx 403 error: directory index of [folder] is forbidden HTTP error 403 in Python 3 Web Scraping MVC4 HTTP Error 403.14 - Forbidden Error message "Forbidden You don't have permission to access / on this server" WAMP 403 Forbidden message on Windows 7 Apache VirtualHost 403 Forbidden Nginx 403 forbidden for all files Emulate a 403 error page 403 Forbidden vs 401 Unauthorized HTTP responses Apache gives me 403 Access Forbidden when DocumentRoot points to two different drives

Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?