Knowledge

403 Forbidden in nginx

#Errors

A 403 Forbidden means nginx found the resource but refuses to serve it. Almost always a file permission problem, a missing index file, or an explicit deny rule.

Published by Mark van Eijk on June 23, 2026 · 1 minute read

  1. About error 403
  2. Why do I see this error
  3. Solution
  4. Fix permissions
  5. Missing index file
  6. Check for deny rules

About error 403

A 403 Forbidden is returned when nginx successfully locates the request but is not allowed to serve it. Unlike a 404, the resource exists, nginx just won't hand it over.

Why do I see this error

The usual causes, in rough order of likelihood:

  • File or directory permissions the nginx worker user can't read or traverse.
  • The URL points at a directory with no index file and autoindex off.
  • An explicit deny rule in the configuration.
  • Wrong ownership on the document root after a deploy.

As always, the nginx error log names the exact reason:

tail -f /var/log/nginx/error.log

You'll see lines like directory index of "/var/www/html/" is forbidden or Permission denied.

Solution

Fix permissions

nginx must be able to read files and traverse (execute bit) every directory in the path. Directories should be 755 and files 644:

sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;

Ownership should match the web server user (www-data on Debian/Ubuntu, nginx on RHEL):

sudo chown -R www-data:www-data /var/www/html

For a Laravel app the web root is the public directory, and only storage and bootstrap/cache need to be writable, see Laravel failed to open stream: Permission denied.

Missing index file

If the request is for a directory, make sure an index file is defined and present:

index index.php index.html;

Avoid turning on autoindex on; on a public server, it exposes your file listing.

Check for deny rules

Search your config for an explicit block you may have forgotten:

location ~ /\.(?!well-known) {
    deny all;
}

That example (blocking dotfiles) is correct, but an over-broad deny is a common self-inflicted 403. Reload after any change:

nginx -t && systemctl reload nginx

Subscribe to our newsletter

Do you want to receive regular updates with fresh and exclusive content to learn more about web development, hosting, security and performance? Subscribe now!

Related articles

Error in the HTTP2 framing layer

A 403 Forbidden means nginx found the resource but refuses to serve it. Almost always a file permission problem, a missing index file, or an explicit deny rule.

Read more →

413 Request Entity Too Large in nginx

A 403 Forbidden means nginx found the resource but refuses to serve it. Almost always a file permission problem, a missing index file, or an explicit deny rule.

Read more →