Encountering a 403 Forbidden error in Nginx means the server understands your request, but refuses to authorize it. Unlike a 404 error where the file simply doesn't exist, a 403 error points to a permissions barrier or an explicit configuration block.
Fixing this issue quickly requires checking file ownership, verifying index files, reviewing access control directives, and inspecting error logs. Let's look at how you can systematically diagnose and resolve this status code on your Nginx server.
Understanding the Nginx 403 Forbidden Root Cause
When a client browser requests a resource, Nginx processes the request against the defined server blocks and location directives. If the server actively blocks access due to security rules, missing files, or incorrect user permissions, it returns the HTTP 403 response.
The first step in troubleshooting isn't guessing; it's reading the error log. Nginx typically records detailed information about why a request failed in the error.log file, usually located at /var/log/nginx/error.log.
Checking this log immediately reveals whether the issue stems from a missing index.html file, a permission denied error on the filesystem, or an allow/deny rule blocking your IP address.
sudo tail -n 50 /var/log/nginx/error.log
Step 1: Check File and Directory Permissions
Incorrect Linux file permissions are the most common reason for a 403 Forbidden error in Nginx. If the Nginx worker process doesn't have read access to your website's root directory or files, it cannot serve them.
By default, Nginx runs under a specific user account, often www-data, nginx, or nobody, depending on your operating system distribution. You need to ensure this user has the appropriate traversal and read permissions.
Fixing Directory Permissions
Directories require execute (x) permissions to allow traversal into them, alongside read (r) permissions to list contents. You can safely reset standard web directory permissions using the find command:
sudo find /var/www/html -type d -exec chmod 755 {} \;
Fixing File Permissions
Files inside your web root generally only require read (r) permissions. You can adjust all files within your document root with this command:
sudo find /var/www/html -type f -exec chmod 644 {} \;
Verifying Ownership
Ownership mismatches also trigger permission blocks. Ensure your web files belong to the correct user and group. You can assign ownership to your web server user like this:
sudo chown -R www-data:www-data /var/www/html
Replace www-data with the actual user defined in your main /etc/nginx/nginx.conf configuration file under the user directive.
Step 2: Verify the Default Index File Exists
If a visitor requests your domain root (e.g., [https://example.com/](https://example.com/)) and Nginx cannot find a default index file inside the specified root directory, it attempts to generate a directory listing. If directory listing (autoindex) is disabled—which it is by default for security reasons—Nginx throws a 403 Forbidden error.
Check your server block configuration to see what index files Nginx looks for:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html index.htm index.php;
}
Make sure that at least one of these files actually exists inside /var/www/html. If you uploaded an home.html file instead of index.html, Nginx won't recognize it automatically without an explicit configuration change or rename.
Step 3: Inspect Nginx Access Control Directives
Nginx allows administrators to restrict access to specific directories or URLs using allow and deny directives, or through HTTP basic authentication. If an IP rule misbehaves, you might block yourself or your users.
Look through your site configuration files for blocks like this:
location /admin/ {
allow 192.168.1.0/24;
deny all;
}
If your current IP address doesn't fall within the allowed subnet, Nginx immediately returns a 403 error. To grant access, update the allowed IP ranges or temporarily comment out the restrictions during testing.
Remember to reload Nginx after making any configuration changes:
sudo nginx -t && sudo systemctl reload nginx
Step 4: Review SELinux or AppArmor Policies
If you're running a Linux distribution with Security-Enhanced Linux (SELinux) enforced—such as RHEL, AlmaLinux, CentOS, or Fedora—standard file permissions might be correct, but SELinux can still block Nginx from reading your web files.
You can check if SELinux is currently enforcing policies:
sestatus
If SELinux blocks Nginx, the error log will often contain explicit AVC denial messages. To fix web context issues on standard document roots, apply the correct SELinux context recursively:
sudo chcon -R -t httpd_sys_content_t /var/www/html
For persistent changes across reboots, use the semanage utility to update file context definitions permanently. You can learn more about managing security modules in the official Red Hat SELinux Documentation.
Step 5: Check Proxy Pass and Upstream Configurations
When using Nginx as a reverse proxy in front of an application server (like Node.js, Python, or a backend PHP-FPM socket), a 403 error can originate from the backend application rather than Nginx itself.
For example, if your upstream application rejects requests missing specific HTTP headers or host definitions, Nginx passes that rejection back to the client.
Ensure your proxy settings forward necessary headers accurately:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
If the backend application checks the incoming host header and rejects unexpected values, failing to include proxy_set_header Host $host; triggers a 403 response from the backend service.
Frequently Asked Questions
Why does a 403 error happen only on specific subpages?
If the homepage loads fine but subpages return a 403 error, the issue is usually related to missing index files in subdirectories, incorrect rewrite rules in your configuration, or restrictive permissions on specific folder paths.
Is a 403 error a server-side or client-side problem?
It is primarily a server-side configuration or permission issue. Even though the client receives the error code, the client cannot fix it directly unless the issue is an incorrect URL path or an unauthorized IP restriction.
How do I check which user Nginx runs as?
You can find the active Nginx user by opening your main configuration file at /etc/nginx/nginx.conf and looking at the user directive near the very top line. Alternatively, run ps aux | grep nginx in your terminal.
Can file permissions break PHP applications like WordPress?
Yes. WordPress plugins and core updates often require writing files to disk. If the web server user doesn't own the wp-content directory, security plugins or core updates might fail and trigger permission warnings or access blocks.