403 Forbidden in Nginx: 6 Causes and How to Fix Each One
A 403 Forbidden page with nginx at the bottom means Nginx received the request and found something at that path, but decided it is not allowed to serve it. Unlike a 404 Not Found, the path usually exists. Unlike a 502 Bad Gateway, the problem is normally in Nginx or the filesystem, not in an app behind it.
Step 1: Check the Error Log
sudo tail -n 30 /var/log/nginx/error.log
The message tells you which cause you have:
| Error log message | Cause |
|---|
directory index of "/var/www/site/" is forbidden | No index file (Cause 1) |
open() "/var/www/site/index.html" failed (13: Permission denied) | File or folder permissions, or SELinux (Causes 2, 3, 5) |
access forbidden by rule | A deny rule in your config (Cause 4) |
| Nothing logged | The 403 probably comes from your app, a WAF or Cloudflare (Cause 6) |
Cause 1: No Index File in the Directory
When you request a folder (like /), Nginx looks for the files listed in the index directive. If none exist and autoindex is off (the default), it returns 403. Fix it by making sure the file exists and is listed:
ls -la /var/www/site/
# in the server block
root /var/www/site;
index index.html index.php;
For PHP sites the most common version of this bug is a server block that lists only index.html, so index.php is never tried.
Cause 2: File Permissions
The Nginx worker runs as www-data on Ubuntu/Debian and nginx on RHEL, AlmaLinux, Rocky and Oracle Linux. It needs read permission on files. A safe standard for a static site:
sudo find /var/www/site -type d -exec chmod 755 {} \;
sudo find /var/www/site -type f -exec chmod 644 {} \;
Avoid chmod 777. It hides the real problem and lets any process on the server change your site.
Cause 3: A Parent Directory Blocks Access
This is the one people miss. Nginx needs execute (x) permission on every directory in the path, not just the last one. Serving from a home folder is the classic trap, because /home/user is often 750:
namei -l /home/user/site/index.html
Any line without x for "others" (or for the Nginx group) breaks access. Either move the site to /var/www (recommended) or grant traverse access: chmod o+x /home/user.
Cause 4: A deny Rule in the Config
Look for rules that block the request:
sudo nginx -T | grep -n -E "deny|allow"
A deny all; in a broad location block, or an allow list that does not include your IP, returns 403 with "access forbidden by rule" in the log. Remember that Nginx ignores .htaccess files, so rules copied from Apache have to be rewritten as Nginx config.
Cause 5: SELinux (RHEL, AlmaLinux, Rocky, Oracle Linux)
If permissions look correct but you still get "Permission denied", SELinux may be blocking Nginx from files that do not carry the web content label:
getenforce
ls -Z /var/www/site
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/site(/.*)?"
sudo restorecon -Rv /var/www/site
Files created in a home folder and then moved keep their old label, which is why mv often triggers this while cp does not.
Cause 6: The 403 Is Not From Nginx
If nothing appears in the Nginx error log, something else is refusing the request: your application (for example a WordPress security plugin), a firewall such as ModSecurity, or Cloudflare's WAF. Check the response headers:
curl -I https://example.com/path
A server: cloudflare header with a Cloudflare-branded page means the block is at Cloudflare; check Security > Events in the dashboard.
Test and Reload
sudo nginx -t && sudo systemctl reload nginx
For other status codes, see common Nginx errors and how to fix them.
Frequently Asked Questions
What does 403 Forbidden nginx mean?
Nginx found the requested path but is not allowed to serve it, usually because of a missing index file, file or folder permissions, a deny rule, or SELinux.
How do I fix 403 Forbidden in Nginx on Ubuntu?
Read /var/log/nginx/error.log. If it says the directory index is forbidden, add an index file. If it says permission denied, give www-data read access to files and execute access to every parent folder.
Should I use chmod 777 to fix a 403?
No. Use 755 for folders and 644 for files. 777 lets any user or compromised process on the server modify your site.
Why do I get 403 for index.php but not index.html?
The index directive probably lists only index.html, or PHP is not configured in that server block. Add index.php and a location ~ \.php$ block that passes requests to PHP-FPM.
Is 403 the same as 401?
No. 401 means you must log in; 403 means the server will not serve the resource even if you are logged in.
Rather Not Debug Nginx at 2 AM?
Every error in this guide is something a managed host fixes for you. RackUp IT managed hosting runs a tuned Nginx, PHP and caching stack with monitoring, backups and SSL handled, so you can spend your time on the site instead of the server.