umask: How New File and Directory Permissions Are Set
A plain file created with touch report.txt in a terminal almost always comes out as -rw-r--r-- (644), and a new directory as drwxr-xr-x (755). Neither touch nor mkdir chose those numbers, and they are not arbitrary — they come from a value called umask attached to every process. Not understanding umask leads to two opposite mistakes: a sensitive file unexpectedly becomes world-readable, or files a service writes never end up group-writable when they need to be.
Special Permissions covered how setuid, setgid, and the sticky bit change an existing file's metadata. umask answers a different question: before an object even exists, what starting permission does it get? chmod corrects an existing file; umask prevents a new one from being born with the wrong permission in the first place.
Here you will see that a regular file starts from a base of 666 and a directory from 777; that umask works through a bitwise AND NOT, not subtraction; how to read umask and umask -S, and change the current value safely; where the mask is actually set — the shell, login.defs, PAM, or a systemd unit — and how to control a service's file permissions with UMask= or an interactive umask. Throughout, keep umask clearly separate from chmod, ownership, and a setgid directory.
Lab Setup
All the examples below work inside the current user's home directory and do not need sudo. umask only affects the current shell process and its children — it never touches system directories. Start each line exactly at the command; the $ or # prompt character is not part of it.
A representative result, which varies by system and distribution:
The first line prints the current umask in octal; the second shows, symbolically, the permissions that are kept at creation time. On an ordinary Ubuntu Server user, this value is commonly 0022 or 0002 — the second is tied to a "user private group" policy, covered in User and Group Accounts.
Note
umask is not a separate program — it is a shell built-in. Because it is a process-specific attribute, its value only applies to the current shell and whatever it spawns afterward. A new terminal window or a new login session starts fresh, reading whatever value its configuration files supply.
The Base Permission and What the Mask Means
When a new object is created, the calling program decides what permission to request from the kernel, but in practice two common bases are used:
- most programs request
0666(rw-rw-rw-) for a regular file; mkdirrequests0777(rwxrwxrwx) for a directory.
Notice that the file base has no x bit at all. A regular file should not accidentally become executable — the execute bit is something you add deliberately with chmod when it is actually needed. A directory's base includes x because it means "enter."
umask decides which bits to remove from that base. It can only restrict, never add. The final permission is not arithmetic subtraction — it is a bitwise "AND NOT":
In other words, every bit set in umask is cleared in the result; every other bit stays as it was in the base.
Why Not Subtraction?
Many guides simplify umask as "subtracted from the base." That gives the right answer most of the time, but it describes the mechanism incorrectly and produces a wrong result for some values. It is easiest to see with the bits themselves. Take mask 0023:
For each triplet, a bit set in umask becomes 0 in the result; other bits are unchanged. Group w (010) and other's w and x (011) are cleared. The result is 0644. If this really were subtraction, 0666 − 0023 would equal 0643 — granting other a nonsensical -wx. So umask does not subtract — it masks out matching bits.
A file's base having no x also has a further consequence: umask's x bits never affect a regular file. umask 0111 leaves a file's 0666 unchanged, because the x bits it would clear are already absent from the base. The same mask does affect a directory, because the directory's base includes x.
Three Common Values
| umask | File result | Directory result | When |
|---|---|---|---|
022 |
644 (rw-r--r--) |
755 (rwxr-xr-x) |
others can read; the default on many systems |
002 |
664 (rw-rw-r--) |
775 (rwxrwxr-x) |
group members can write; useful for team work |
077 |
600 (rw-------) |
700 (rwx------) |
only the owner has access; suited to sensitive data |
077 clears every group and other bit, so new files are only open to their owner. This is a safe default for a session that creates secrets or personal data frequently.
Testing It Directly
Now change the value and watch the result directly. umask 0027 leaves the group able to read, and clears everything for other:
Expected result:
The file's base was 0666; 0027 cleared group w and other rwx, leaving 0640. The directory's base was 0777; the same mask left 0750. Now try a stricter mask:
Warning
These examples only changed umask temporarily, for the current interactive shell. The value disappears when that shell closes. Changing a global umask in /etc/profile, /etc/login.defs, or a systemd unit affects the whole system or an entire service — test it in a lab environment first.
Fixing an Existing File with chmod
umask only applies at creation time. It does not recompute an existing file — chmod is needed for that:
umask is prevention; chmod is correction. The right umask keeps files from starting out with a wrong permission; chmod fixes an object that was already created incorrectly, or that needs a special mode. Neither one substitutes for the other.
What umask Does Not Affect
umask governs only one part of the permission model. Do not confuse it with these neighboring ideas:
- Ownership. A new object's owner and group come from the creating process and any
setgiddirectory policy, not fromumask— covered in Ownership. - Special bits.
umaskdoes not automatically placesetuid,setgid, or the sticky bit on a new object; those come fromchmodorsetgidinheritance, as in Special Permissions. - Existing files. As shown above, the mask only affects creation.
cpand archives.cp -p,cp -a,tar, and similar tools may try to preserve source permissions, bypassingumaskentirely. After a copy or restore, check permissions withstatrather than trustingumask.
A setgid Directory and umask Together
In a shared directory, setgid makes new files inherit the directory's group, but it does not by itself grant group write access. That access still depends on umask. Suppose a setgid directory exists, but the session is running with umask 0022:
umask 0022
mkdir team
chmod 2775 team
touch team/report.txt
stat -c '%A %a %U:%G %n' team team/report.txt
Even though the directory is setgid, the file comes out 0644 — a group member can read it, but not write to it. If group write is required, the session needs umask 0002 instead:
Now the file comes out 0664. The conclusion: "files in the team directory are not group-writable" is often caused not by a missing setgid, but by the wrong umask.
Where umask Comes From and How It Is Kept
umask is inherited from process to process, so "where is it set" matters. The main sources are:
- Shell built-in. An interactive
umask 0027affects only the current shell and its children. Writing it into a user's profile (~/.bashrc,~/.profile) makes it persistent, but only for that user's interactive shell. /etc/login.defs. TheUMASKdirective sets the default mask applied during login.- PAM (
pam_umask). Many distributions set the login session's mask through a PAM module, which may choose a value based onlogin.defsor the user's group. - systemd. For a service or the user manager, the mask is set explicitly with the
UMask=directive in a unit file — the most reliable method for daemon-created files.
Always check the actual current session's value directly — do not assume the effective value just because a configuration file says so:
grep only shows the text in login.defs; it does not account for a later override by PAM or a shell profile. The final proof is always the output of the umask command itself.
Note
On Ubuntu and Debian, an ordinary user often belongs to their own private group (for example, ali:ali). Because of that, umask 0002 is considered a safe default: group write in practice only applies to the user themselves. The RHEL family follows a similar "user private group" approach. In a shared, multi-member group, apply 0002 deliberately, after checking the group's actual policy.
Practical Scenario: Service Files Are Created Too Openly
Suppose report.service writes report files into /var/lib/report/out/. An audit found these files at 0644 — readable by any local user on the system. Policy requires only the service owner and the report group to view the reports. The cause is the service's umask, which is 0022.
This is a production change to a systemd unit. Do not proceed without a VM snapshot or configuration management, and a rollback plan.
1. Check the Current State Without Changing Anything
systemctl show -p User -p Group -p UMask report.service
sudo find /var/lib/report/out -xdev -type f -printf '%m %u:%g %p\n' | head
systemctl cat report.service
systemctl show reports the service's effective UMask; find shows the actual mode of existing files. If UMask is empty or 0022, it explains why new files come out 0644.
2. Determine the Intended Policy
Files should be readable by the owner and group, closed to everyone else. umask 0027 fits: group read stays, every bit is cleared for other. If group write is also needed, 0007 is the choice.
3. Backup and a Controlled Change
First save or note the existing drop-in, then set UMask through a drop-in file:
In the editor that opens, add only this:
systemctl edit creates the drop-in /etc/systemd/system/report.service.d/override.conf and does not touch the main unit. This makes rollback simple: removing the drop-in is enough.
4. Reload and Verify
sudo systemctl daemon-reload
sudo systemctl restart report.service
systemctl show -p UMask report.service
Once UMask=0027 is confirmed, check the next report the service creates:
New files should come out 0640. Existing files keep their old mode — correct them separately with chmod, matching policy, only after a backup plan is confirmed.
5. Rollback
If the change has an unexpected effect, remove the drop-in:
sudo systemctl revert report.service
sudo systemctl daemon-reload
sudo systemctl restart report.service
systemctl show -p UMask report.service
systemctl revert undoes drop-ins created by systemctl edit and returns the service to its distribution-provided state. Check the service logs and new file modes again afterward.
Common Mistakes
Thinking umask Adds Permission
umask only removes bits. umask 0000 does not add x to a file's base — a regular file is still created at 0666. Use chmod when an execute or special bit is actually needed.
Treating umask as Arithmetic Subtraction
0666 − umask gives the right answer for many values, but the mechanism is a bitwise AND NOT. umask 0023 gives 0644 for a file, not 0643. When in doubt, confirm the result with stat.
Expecting the Same Result for a File and a Directory
The same mask affects a file's base (0666) and a directory's base (0777) differently. umask's x bits never touch a file, but they do affect a directory. That is why umask 0022 gives a file 0644 and a directory 0755.
Checking a Global umask with an Interactive One
Your login shell's umask does not show a service's or a cron job's mask. Check each context separately: systemctl show -p UMask for a service, and an explicit umask output inside a cron job.
Blaming a Shared Directory's Permission Problem Only on setgid
If files are not group-writable, the cause is often umask 0022, not a missing setgid. setgid inherits the group; umask controls the write bit. Fix both together.
Treating a Configuration File as the Effective Value
The UMASK value in /etc/login.defs is one source, not the single source of truth. PAM, a shell profile, or systemd can override it. Confirm the final value only by running umask in the exact context that matters.
Exercises
- Record the current
umaskwithumaskandumask -S. Then set0022,0002,0027, and0077in turn, creating one file and one directory each time. Fromstat -c '%A %a %n'output, explain which bits each mask removed. - Set
umask 0111and create one file and one directory. Explain, at the bit level, why the file's mode did not change while the directory's did. - Create a
setgiddirectory (chmod 2775). Compare the mode of a new file inside it underumask 0022versusumask 0002. Show which mask actually allows group write. - Compare the output of
grep -i '^UMASK' /etc/login.defsagainst theumaskcommand's own result. If they differ, determine which source — shell profile or PAM — set the effective value. - For a hypothetical service, take the requirement that files should be readable only by the owner and group. Choose the matching
umask, describe how you would set it asUMask=, and which command verifies the result. Do not change a real service.
Verification criterion: in every answer, show the base (0666/0777), the mask, and the three-step AND NOT operation — not just the final mode number.
When you finish the lab, inspect the target read-only:
Only if the result shows nothing but the ~/lab/umask test tree:
Warning
rm -rI deletes the test tree with no undo mechanism. Run it only after confirming the absolute boundary with the find command above. Save any results you want to keep elsewhere first; do not use this command on a production directory.
References
- Linux man-pages:
umask(2): https://man7.org/linux/man-pages/man2/umask.2.html - POSIX.1-2024: the
umaskutility: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/umask.html - Linux man-pages:
open(2): https://man7.org/linux/man-pages/man2/open.2.html - Linux man-pages:
login.defs(5): https://man7.org/linux/man-pages/man5/login.defs.5.html - Linux man-pages:
pam_umask(8): https://man7.org/linux/man-pages/man8/pam_umask.8.html - systemd:
systemd.exec(5)(UMask=): https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html - GNU Bash Reference Manual: Bourne shell builtins (
umask): https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html