Linux VPS

chown: change file owner and group in Linux

Use chown and chgrp to change who owns files on your Linux server, fix web root ownership after an upload, work recursively and understand how symbolic links are handled.

BeginnerLinux server5 min read

Every file on Linux belongs to one user and one group. When a web server cannot write to an upload folder, or files copied as root are suddenly read-only for your app, the fix is usually a change of owner rather than looser permissions. This guide covers chown and chgrp, recursive changes, symbolic links and typical web root setups.

Before you start

  • A Linux VPS with Ubuntu 22.04 or 24.04, Debian 12, or AlmaLinux or Rocky Linux 8 or 9.
  • An SSH session with sudo. Only root can give a file to another user.
  • The user and group names you want to use. Check them with id deploy or getent group www-data.

See the current owner

Bash
ls -l /var/www/example.com
-rw-r--r-- 1 root     root     1024 Nov  9 10:02 index.php
drwxr-xr-x 2 deploy   deploy   4096 Nov  9 10:02 uploads

The third column is the owner and the fourth is the group.

Change the owner

Bash
sudo chown deploy index.php

The group stays as it was.

Change owner and group together

Separate them with a colon:

Bash
sudo chown deploy:www-data index.php

Variations:

  • chown deploy: file: owner deploy, group set to deploy's primary group.
  • chown:www-data file: change only the group.

Change only the group with chgrp

chgrp does just the group, and a normal user may use it to move their own file into any group they belong to:

Bash
chgrp www-data index.php

Change ownership recursively

-R applies the change to a folder and everything under it:

Bash
sudo chown -R deploy:www-data /var/www/example.com

Warning: Double-check the path before pressing Enter. A recursive chown on the wrong folder, such as /, /etc or /usr, can break sudo, SSH and system services, and is very hard to undo by hand. GNU chown refuses to work on / itself, but a typo such as an extra space can still point it at the wrong place.

Add -v to list every change, or -c to list only files that actually changed.

By default, chown on a symlink changes the file the link points to, not the link itself:

Bash
sudo chown deploy current

To change the link itself, use -h:

Bash
sudo chown -h deploy current

With -R, chown does not follow symlinks to folders by default, which is the safe behaviour. It changes the link, not its target. The options -L (follow all links) and -H (follow links given on the command line) change that. Avoid -L unless you are sure where every link leads, because a link to /etc would hand system files to your user.

Copy ownership from another file

To match a known-good file:

Bash
sudo chown --reference=index.php new-page.php

This sets the same owner and group in one step.

Typical web root ownership

A common, safe layout is:

  • Files owned by your deploy user, so you can update the site over SSH or SFTP.
  • Group set to the web server group, so it can read them.
  • Write access for the web server only on folders that need it, such as uploads or cache.

On Ubuntu and Debian the web server runs as www-data. On AlmaLinux and Rocky it is nginx or apache.

Bash
sudo chown -R deploy:www-data /var/www/example.com
sudo chmod -R u=rwX,g=rX,o= /var/www/example.com
sudo chmod -R g+w /var/www/example.com/uploads

The web server can read the whole site and write only to uploads. If the site is compromised, the attacker cannot change your code. App-specific advice, such as for WordPress, is in Set correct web root permissions on Linux.

Change files with a numeric ID

You can use numeric IDs instead of names, which helps after deleting a user or when restoring files from another server:

Bash
sudo chown 1001:1001 data.db

To hand every file of an old ID to a new account:

Bash
sudo find /var/www -xdev -uid 1001 -exec chown deploy {} +

Check it works

Bash
stat -c '%U:%G %n' /var/www/example.com/index.php
deploy:www-data /var/www/example.com/index.php

Then test from the app's point of view. For example, check the web server can read a file:

Bash
sudo -u www-data cat /var/www/example.com/index.php > /dev/null && echo OK

Troubleshooting

  • "Operation not permitted" without sudo: only root can change a file's owner. Run the command with sudo.
  • "invalid user" or "invalid group": the name does not exist. Check the spelling with getent passwd or getent group.
  • Ownership resets after a deploy: the deploy tool extracts files as root or as another user. Run it as the right user, or add a chown step at the end.
  • App still cannot write after chown: the folder may lack write permission for the group, or a parent folder lacks x. Check every level with namei -l /path/to/folder.
  • "Operation not permitted" even as root: the file is immutable. Check with lsattr and remove the flag with chattr -i.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.