A “Permission denied”, or a 403 on a website, is almost always one of two things: the file’s owner is not who the service runs as, or a permission is missing on the file or on one of the folders in its path. See with ls -l who owns it and what is allowed, and with namei -l /full/path the first folder in the path that blocks. You fix it with chown (change the owner) and chmod (change the permissions). On an unmanaged VPS this is yours to do.
Reading what ls -l says
A line like -rw-r--r-- 1 deploy www-data 1200 Oct 10 site.php has three parts. The first ten characters are the type and permissions (- file, d folder; then three groups of three: owner, group, others, each with r read, w write, x execute). Then come the owner (deploy) and the group (www-data).
| Number |
Meaning |
When to use it |
| 644 |
Owner reads and writes; group and others only read |
A site’s files |
| 755 |
Owner reads, writes, executes; others read and execute |
Folders, and programs |
| 600 |
Only the owner reads and writes |
Secrets: keys, files with passwords |
| 700 |
Only the owner gets in |
Private folders, like ~/.ssh |
| 777 |
Everybody does everything |
Never. It cures the symptom and opens the door to whoever gets in through any other site. |
Step by step for a site giving 403 or “Permission denied”
| 1 |
Find out who the service is. ps aux | grep -E "nginx|apache|httpd|php-fpm" | head. On Debian and Ubuntu it is usually www-data; on AlmaLinux and Rocky, nginx or apache.
|
|
| 2 |
Look at the whole path. namei -l /var/www/yourdomain.tld/public/index.php shows the permissions of each folder down to the file. The server must be able to traverse (x permission) every folder in the path, not just read the file. A closed home folder (/home/user at 700) blocks everything inside it.
|
|
| 3 |
Set the owner right. If the site is managed by a user of yours and served by another, give the right group: sudo chown -R deploy:www-data /var/www/yourdomain.tld. Or let the service own only the folders it must write to (uploads, caches).
|
|
| 4 |
Set the permissions to sensible values: sudo find /var/www/yourdomain.tld -type d -exec chmod 755 {} \; and sudo find /var/www/yourdomain.tld -type f -exec chmod 644 {} \;.
|
|
| 5 |
Give write access only where needed. An uploads folder needs write for the service (for example chmod 775 with the service’s group); the rest of the site does not.
|
|
| 6 |
Test again and read the error log. If it is still denied once everything is right, it may be SELinux or AppArmor: when they block a service.
|
|
|
Mind the -R in the wrong place. chown -R or chmod -R on a folder higher up than you meant (the root /, /etc, /home) can break the whole system: SSH stops accepting keys with loose permissions, and system programs need their owners. Read the path twice before pressing Enter.
|
|
Do not make root the owner of the site. If a root task writes into the folder, the files end up root’s and the site cannot change them. Run that task as the right user: cron that does not run.
|
|
Locked yourself out by touching system permissions? The panel console gets you in without the network: tell us what you did.
Open a support ticket
|
RECOMMENDED PRODUCT VPS server with root access Resources of your own, the OS you choose, reinstall whenever you like. from $8.39/mo (3-year plan, with coupon) See plans |