Guides

403 Forbidden: Permissions, File Ownership and Web Server Rules

A practical guide to the 403 Forbidden error: the three causes (permissions, ownership, server rules), the commands to fix them on Ubuntu, cPanel and Plesk, and how to verify the fix.

UptimeMag editorial team · 9 October 2026 · 6 min read

403 Forbidden: permessi, proprietario del file e regole del server web

The quickest way to check

First things first: a 403 almost never has anything to do with the specific file you were looking at — it's usually about how the folder is configured. First test, thirty seconds: try uploading a different file to the same directory (even an empty file called test.html). If that one returns 403 too, the problem lies in the folder or the server configuration, not in the single file. Second test: open the server's error log — don't just trust the blank page in your browser. On Ubuntu with Nginx the file is /var/log/nginx/error.log (the same path applies to package installs on RHEL and CentOS), as stated in the official Nginx documentation. The command to watch it live is:

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

The line that matters is the one containing the IP address of your test request and the words "Permission denied" or "access forbidden by rule": the former points to a permissions/ownership issue, the latter to a configuration rule.

What the error actually means

The server understood the request and found (or should have found) the file, but decided not to serve it. It's not a network issue, and the site isn't "down": it's a locked door, and the wrong key could be in one of three different places.

Cause 1: File permissions (the most common)

This is the most frequent cause after an FTP upload, a backup restore or a migration. The web server process (Nginx, Apache) runs as a system user — typically www-data on Ubuntu — and that user needs to be able to read the file and traverse every folder along the path.

How to tell if this is your issue: from the shell, inside the site's directory:

ls -la

If folders don't show rwxr-xr-x (755) or files don't show rw-r--r-- (644), this is your cause. Watch out for parent folders too: a single folder along the path missing the execute bit (x) is enough to block everything underneath, even if the final file itself has the correct permissions.

How to fix it, on Ubuntu, from the site's root folder (replace /var/www/yoursite with the actual path):

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

Running find separately for directories (-type d) and files (-type f) is precisely to avoid applying the same value to everything: a folder with 644 can't be traversed, while a file with 755 becomes executable when it shouldn't be. On Plesk, the official procedure, described on the Repair Kit support page, is essentially identical: find /var/www/vhosts/example.com/httpdocs/* -type d -exec chmod 0755 {} \; for folders and the equivalent -type f -exec chmod 0644 for files, with the path on Plesk always sitting under /var/www/vhosts/.

Why never use 777. With 777, anyone with access to the system — even another site on the same shared server, if isolation isn't properly configured — can write to and modify your files. It's the most common cause of WordPress sites being silently compromised: it doesn't fix the 403 any better than 755, it fixes it in exactly the same way but leaves the door wide open to everyone.

How to confirm it's fixed: reload the page. If you're dealing with browser caching, open it in a private/incognito window. From the shell, ls -la should show 755 on the folders and 644 on the files involved.

Cause 2: Wrong file ownership

Permissions tell you what can be done, ownership tells you who can do it. A file can have 644 and still return 403 if it's owned by a different user than the one the web server expects, because PHP-FPM or the web server module reads files as a specific user, and intermediate folders deny access to "others".

How to tell if this is your issue: compare the owner shown in the ls -la output with the user running the site's PHP-FPM pool. On a typical Ubuntu setup with PHP-FPM, the pool's user is specified in the user = directive of the pool file under /etc/php/8.3/fpm/pool.d/. If the file belongs to root or another account while the pool runs as the site's own user, that's a typical ownership conflict following a backup restore performed as root, or an rsync run with sudo without preserving ownership.

How to fix it, on Ubuntu (replace user:group with the site's actual user, e.g. www-data:www-data or the dedicated pool user):

sudo chown -R user:group /var/www/yoursite

How to confirm: ls -la should show the correct owner on folders and files, and the site should respond without a 403.

Cause 3: Server configuration rules

In this case permissions and ownership are already correct, but the server itself is saying no: a deny all; directive inside an Nginx location block, a Require all denied rule in an Apache .htaccess file, HTTP Basic authentication being required but not supplied, or an explicit restriction on a folder (typically on /wp-admin, /xmlrpc.php or upload folders, to block script execution).

How to tell if this is your issue: the file has correct permissions and ownership, yet the 403 persists. Search the site's configuration:

grep -r "deny" /etc/nginx/sites-available/

or, for Apache/.htaccess, open the .htaccess file in the relevant folder and look for Deny from all or Require all denied lines. In the Nginx log, the telling line, as noted in the official documentation, reports the severity and message of the event logged by the error_log directive.

How to fix it: comment out or remove the rule if it's no longer needed, or correct it to restrict it to the right IP or path. After any change to the Nginx configuration:

sudo nginx -t && sudo systemctl reload nginx

The nginx -t command checks the syntax before reloading: if there's an error, the server keeps running on the previous configuration instead of crashing.

The cPanel case

On cPanel the logic is the same — 755 for folders, 644 for files — but the owner must always be the cPanel account user for that site, never root and never a generic user such as nobody: this is the most common cause of 403 errors after a manual backup restore or a transfer from another host. The filesystem under cPanel is the same Linux filesystem, so the same find ... -exec chmod commands work identically; the only difference is that you need to pass the correct account path, generally under /home/cpanelusername/public_html/. To fix ownership in one go:

chown -R cpanelusername:cpanelusername /home/cpanelusername/public_html

The Plesk case

On Plesk, sites live under /var/www/vhosts/domainname/httpdocs/, and the official tool for catching these issues is plesk repair fs, which flags files or directories that are writable by anyone or not readable/writable by their owner — insecure permissions that can indicate a security breach. To see in detail which files are out of line before fixing anything, run it first in check-only mode:

plesk repair fs -v -n

and then apply the same find commands with chmod 0755 for folders and chmod 0644 for files, substituting the domain name in the path, as described on the official Plesk support page.

When it's not your fault: the provider's side

If the site was online, you haven't touched any files or permissions, and the 403 suddenly appears across the whole domain (not just on a single page), it could be an infrastructure-side issue: an automatic panel update that overwrote a configuration rule, a backup restore performed by the provider with the wrong user, or a change to a WAF/CDN sitting in front of the server. In this case, open a support ticket and attach: the exact URL returning 403, the precise time it appeared, and, if possible, the output of ls -la on the site's folder taken from an SSH session or the panel's File Manager. Without these three pieces of information, support will have to redo the diagnosis you've already completed yourself in two minutes.

Summary of correct values

Element Correct value Verification command
Folders 755 (rwxr-xr-x) ls -ld foldername
Files 644 (rw-r--r--) ls -l filename
Owner PHP-FPM pool user or hosting account user ls -la (third column)
Never 777 on folders or files —

Written with the help of artificial intelligence and checked by the editors (EU AI Act, art. 50).