403 Forbidden with Nginx: The Usual Causes
Nginx serves a 403 Forbidden. Unlike a 404, the file is found — Nginx just won't hand it over. It's almost always file permissions or a missing index. Here's the short list to check.
Nginx answers a request with:
403 Forbidden
A 403 is different from a 404. A 404 means "I couldn't find it." A 403 means "I found it, but I'm not allowed to serve it to you." So the file exists — the problem is access. For a static site, it's nearly always one of two things: Nginx can't read the file, or there's no index page to show for a directory.
Always start with the error log
It names the real reason almost every time:
tail -f /var/log/nginx/error.log
# "Permission denied" → a permissions problem (Cause 1)
# "directory index of ... is forbidden" → a missing index (Cause 2)
Cause 1: Nginx can't read the files
Nginx runs as an unprivileged user (www-data or nginx). That user must be able to traverse every directory down to the file and read the file itself. A common cause is files living under /home/you/, which others can't enter.
namei -l /var/www/mysite/index.html # shows permissions at each level — find the block
sudo chown -R www-data:www-data /var/www/mysite
sudo chmod -R o+rX /var/www/mysite # readable; +X = traverse dirs, not mark files executable
Every directory in the path needs the "execute" (traverse) bit, or Nginx can't reach the file even if the file itself is readable.
Cause 2: A directory with no index file
If a request maps to a directory and there's no index.html (or whatever your index directive lists), Nginx won't list the contents by default — it returns 403:
location / {
root /var/www/mysite;
index index.html; # make sure this file actually exists in the dir
}
Either add the index file, or (only if you want a file listing) enable autoindex on;.
A 403 says "found it, forbidden." So skip the "is the path right?" hunt — go straight to permissions and the index file. The error log tells you which in one line.
The checklist
- 403 = the file exists but access is refused (not a 404 "missing").
- Read
/var/log/nginx/error.log— "Permission denied" vs "directory index forbidden". - Permissions: Nginx's user needs read + traverse (
o+rX) all the way down. - Directory request: ensure the
indexfile exists (or setautoindex on).
Stop reading, start building
This pairs with a hands-on BytExplorer course — do it on your own machine and actually keep the skill.