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.

BytExplorer 5 min read July 1, 2026

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

  1. 403 = the file exists but access is refused (not a 404 "missing").
  2. Read /var/log/nginx/error.log — "Permission denied" vs "directory index forbidden".
  3. Permissions: Nginx's user needs read + traverse (o+rX) all the way down.
  4. Directory request: ensure the index file exists (or set autoindex on).
Put it into practice

Stop reading, start building

This pairs with a hands-on BytExplorer course — do it on your own machine and actually keep the skill.

More in Troubleshooting