Troubleshooting guide · migration-hosting · Published 2026-08-16 · 3 min read
Website file permissions and ownership sync
File permissions and ownership sync explained: the 403/500 symptoms, ownership mismatch after a move, and safe chown/chmod.
- ·Permissions and ownership
- ·The 403 and 500 symptoms
- ·Re-sync after a move
What permissions and ownership control
On a Unix-like server, a file and every directory have two properties that decide who can read, write and run them: a permission mode (the read/write/execute bits) and an ownership (the user and group the file belongs to). The webserver process, the FTP user and the shell user all access files as specific operating-system users, and if their identity does not match the file's owner or group, access fails.
Two common failures trace back to this:
- 403 Forbidden when the file exists but the webserver user does not have permission to read it, or the user lacks permission to traverse one of the parent directories.
- 500 or a partial site when a PHP app cannot write to the upload or cache directory because the directory is not owner-writable by the webserver process.
Ownership mismatch after a move
This is the classic post-migration bug. You download the site as your local user or the old FTP user, upload it to the new host, and every file is owned by that upload identity rather than by the webserver user (often apache, www-data, nginx or nobody). The files exist, but the webserver cannot read or write them, producing 403s or white screens.
The fix is to re-sync ownership to the account and group the webserver runs as. On a cPanel-style host, files belong to the account user, and directories typically get group write for that user.
# Own everything by the expected application user and group
chown -R user:user /home/user/public_html
# Files read-only for web execution; directories writable by the group
find /home/user/public_html -type d -exec chmod 755 {} \;
find /home/user/public_html -type f -exec chmod 644 {} \;
| Item | Safe default | Why |
|---|---|---|
| Files | 644 | Read for all, write for owner |
| Directories | 755 | Traverse and read, owner writes |
| Upload/cache dir | 755 + owner-writable, or 775 group-writable | App must write |
| Executables / scripts | 755 | Owner can run |
A safer sync, and what not to do
Blindly running a single chmod -R 777 hands every file to every local user and is the fix that creates a security hole. Prefer a targeted pass: re-own the tree, apply 644/755 broadly, then set group-write only on the directories the application actually needs to write (uploads, cache, logs), using the account user as owner. Add an optional setgid bit on shared directories so new files inherit the group.
chmod g+ws /home/user/public_html/uploads
On a managed host some directories are intentionally owned by a different user (for example nobody for certain caches), so know the panel's layout before you change everything. The 403 Forbidden guide distinguishes an ownership problem from a server rule problem, and the move to new hosting and host migration checklist guides make the ownership resync a named step in the migration instead of a fix found later.