List of Articles Icon

Knowledge Base

Guides and answers for your VPS, the client area, and billing

Fixing 403 Forbidden errors on your website

What this is

403 Forbidden is the web server saying: I found what you asked for, and I refuse to serve it. Unlike a 502 (backend dead) or a 404 (not there), a 403 is about permission and policy, and the server's error log states the exact reason, so start there:

tail -20 /var/log/nginx/error.log     # nginx
tail -20 /var/log/apache2/error.log   # Apache

Permission denied points at filesystem permissions; directory index of ... is forbidden points at a missing index file; access forbidden by rule points at a deny rule. Match the message to the section below.

Cause 1: ownership and permissions (the post-upload classic)

The most common story: files uploaded over SFTP as root land owned by root, and the web server, which runs as its own user (www-data on Debian/Ubuntu, nginx/apache on RHEL-family), isn't allowed to read them. Fix ownership, not the world:

chown -R www-data:www-data /var/www/yoursite
find /var/www/yoursite -type d -exec chmod 755 {} \;
find /var/www/yoursite -type f -exec chmod 644 {} \;

Directories 755, files 644, readable by the server, writable only by the owner (how the permission model works, if the numbers feel like magic). And the standing rule: never chmod -R 777. It "fixes" the 403 by making every file writable by every process on the machine, which is how web shells get planted. If 777 would have fixed it, correct ownership fixes it properly.

One subtle variant: the server needs execute (traverse) permission on every parent directory of the file. A 700 home directory above your web root produces 403s even when the files themselves are perfect.

Cause 2: no index file

Requesting a directory (https://yourdomain.com/) serves its index file (index.html, index.php), and if none exists, the server refuses to show a listing and returns 403. Either your upload landed in the wrong place (check the site actually lives where the config's root points, cause 4) or the index file is genuinely missing or misnamed.

Cause 3: a deny rule

Config blocks like deny all, Apache Require all denied, IP allowlists you set up and forgot, or security rules in .htaccess (WordPress security plugins write these liberally) all produce 403s on purpose. The error log's forbidden by rule line tells you which request matched; grep the config for deny and check .htaccess files in the site root.

Cause 4: wrong document root

If everything 403s (or you see a default page), the server may be looking at an empty or different directory than the one you uploaded to. Compare the config's root/DocumentRoot against where the files actually are, grep -r "root" /etc/nginx/sites-enabled/.

Cause 5: SELinux (AlmaLinux, Rocky)

On RHEL-family distros, files moved (not copied) into the web root can carry the wrong SELinux context, and the server gets Permission denied even though classic permissions look perfect, the tell is a 403 that survives correct ownership. Restore the expected context:

restorecon -Rv /var/www/yoursite

Still 403?

Cloudflare users: an orange-cloud 403 with a Cloudflare error page is their WAF or a firewall rule you set there, not your server; check the Cloudflare dashboard's security events. Otherwise, the error log line for the exact failing request (it logs the full path it tried) settles every remaining case.

Still need help?

You can open a support ticket. So we can help on the first reply, it's worth mentioning:

  • the VPS and the site's domain,
  • the exact line from the web server's error log for a failing request,
  • the ownership and permissions of the files involved (the ls -la output helps).
  • "Why does my site say 403 Forbidden after I uploaded it?"
  • "What permissions should website files have?"
  • "Why is chmod 777 a bad fix?"
  • "Directory index is forbidden, what does that mean?"
  • "403 on AlmaLinux/Rocky even though permissions are right (SELinux)?"
Last reviewed: 2026-07-02