Guides

chmod command: 777, 755, +x and recursive, explained properly

What chmod 777, 755 and +x actually set, octal vs symbolic mode, chmod -R without breaking directories, and why chmod 777 is almost never the right fix.

Published ~8 min read

Short answer: chmod MODE FILE sets who can read, write and execute a file. The mode is three digits (chmod 755 script.sh) or a symbolic change (chmod +x script.sh), each digit or letter covering the owner, the group and everyone else in that order. Below: what the common modes mean, recursive chmod without breaking directories, and why chmod 777 is almost always the wrong fix.

Octal mode: the three digits

Each digit is read, write and execute added up — read = 4, write = 2, execute = 1 — for the owner, the group, then everyone else:

ValuePermissionsMeaning
7rwx4 + 2 + 1 — read, write, execute
6rw-4 + 2 — read, write
5r-x4 + 1 — read, execute
4r--4 — read only
0---no permissions at all
chmodSymbolicUse it for
644rw-r--r--Ordinary files: HTML, images, configs
755rwxr-xr-xDirectories, and scripts or binaries anyone may run
700rwx------Private scripts and directories — only the owner touches it
600rw-------Private files — SSH keys, credentials, .env files
777rwxrwxrwxAlmost never the right answer — see below
Set a mode by number
chmod 755 deploy.sh
chmod 644 index.html
chmod 600 ~/.ssh/id_ed25519

To go the other way — tick the permissions you want and read off the octal number, or paste a mode and see what it means — the chmod calculator does both, including setuid, setgid and the sticky bit below.

Symbolic mode: +x, -w, u/g/o

Symbolic mode changes permissions relative to what a file already has, rather than replacing the mode outright — the most common reason to reach for it is making a script executable without touching its read and write bits:

CommandWhat it does
chmod +x fileAdd execute for owner, group and others
chmod -x fileRemove execute for everyone
chmod u+x fileAdd execute for the owner only
chmod g+w fileAdd write for the group
chmod o-rwx fileRemove all permissions for everyone else
chmod a+r fileAdd read for everyone (a = owner + group + others)
chmod u=rwx,g=rx,o=rx fileSet exact permissions per class — equivalent to 755

u is the owner (user), g the group, o everyone else, and a all three together. + adds a permission without touching the others, - removes one, and = sets the class to exactly what follows, clearing anything not listed.

Recursive chmod: -R, and doing it properly

The quick version
chmod -R 755 /var/www/site

Set directories and files to different modes in one pass with find instead:

Directories get 755, files get 644
find /var/www/site -type d -exec chmod 755 {} +
find /var/www/site -type f -exec chmod 644 {} +

A directory needs its own execute bit before anything can cd into it or open a file inside it by name, which is why 755 — not 644 — is the baseline for directories even when nothing in them should be run as a program.

Why chmod 777 is (almost) always wrong

777 gives read, write and execute to the owner, the group, and every other account on the system — including a web server’s user if another site on the same machine is compromised, or any process that can reach the file at all. On a directory it also lets anyone create or delete files inside it, not only change the ones already there.

Almost every “just chmod 777 it” fix found online is really an ownership problem in disguise: a file owned by root that a service running as www-data needs to write to. The fix is chown, not a wide-open mode:

sudo chown www-data:www-data /var/www/site/uploads
sudo chmod 755 /var/www/site/uploads   # or 775 if the group also needs write access

A 403 Forbidden from nginx is the error that most often tempts people toward 777 — it is almost always this same ownership mismatch, not a missing permission bit.

Permission denied despite the right mode

  • Every parent directory needs execute, too. chmod 755 on the file itself does nothing if /var/www/site is 700 — a process needs execute on every directory in the path to reach the file, not only on the file.
  • SELinux or AppArmor can block access a chmod mode allows — on Rocky and AlmaLinux, ls -Z shows the SELinux context, and restorecon -Rv path resets it to the distribution’s default for that location.
  • A mounted filesystem can ignore chmod outright — a FAT32 or network share mounted without permission options takes whatever mode was given at mount time, not what you set afterward.

If a command itself refuses to run after chmod +x, see bash: Permission denied — the cause is usually one of the three above, or a noexec mount.

SSH refuses a key with the wrong mode for an entirely different reason — sshd will not trust a private key or .ssh directory that other accounts can write to; see Permission denied (publickey).

Frequently asked

What does chmod 777 do, and why is it a bad idea?

It gives read, write and execute to the owner, the group and every other account on the system — including a web server's own user if another site on the same machine is compromised. Almost every case where 777 'fixes' something is really an ownership problem: chown to the right user and keep the mode at 644 or 755.

What is the difference between chmod 644 and 755?

644 (rw-r--r--) lets the owner read and write and everyone else read — the normal mode for files. 755 (rwxr-xr-x) adds execute for everyone, which directories need to be entered and scripts need to be run.

How do I chmod recursively without making every file executable?

chmod -R applies the same mode to everything, files included. Use find instead: find path -type d -exec chmod 755 {} + for directories, find path -type f -exec chmod 644 {} + for files.

Why does chmod +x not work?

It usually does — check with ls -l that the x actually appears. If the script still will not run, the more common cause is a missing or wrong shebang line (#!/bin/bash) or trying to run it without the leading ./ (./script.sh).

Related articles

All guides