Why umask 022 Makes Files 644 but Directories 755

Measure Linux creation modes and see why umask 022 yields 644 files and 755 directories, plus when default ACLs change the result.

By Network Nuts ยท Published 2026-10-19

umask 022 gives you 644 for new regular files and 755 for new directories because Linux does not start from the same base mode for both object types. In the common case, files start from 0666, directories start from 0777, and the mask clears bits from those starting values. This lab measures those modes with native shell commands. The final section explains a documented exception, default ACLs on the parent directory, which this lab does not test. Red Hat's RHEL 9 permissions guide and the umask(2) manual page describe the same model. (docs.redhat.com)

Lab environment

This walkthrough is based on a verified lab run in a disposable working directory.

  • Tested OS: Ubuntu 26.04 LTS
  • Shell: Bash 5.3
  • Commands used: umask, mkdir, touch, chmod, stat -c, and find -printf
  • Scope: temporary user-owned files only

The behavior demonstrated here is standard Linux file-creation behavior. The explanation also matches Red Hat's documented permission model for RHEL, but the measured command output in this article came from Ubuntu, not from a RHEL host. Red Hat's file-permission documentation documents the 666 and 777 base modes, while open(2) and mkdir(2) document how the process umask filters creation modes. (docs.redhat.com)

Prerequisites

You need:

  • a Linux shell with Bash
  • stat with -c format support
  • find with -printf support so you can reproduce the final verification output exactly
  • permission to create and remove files in a new empty working directory

This lab creates only these paths inside the disposable folder: mask-022/, mask-027/, mask-077/, and details.txt. The stat -c format used below is documented in stat(1), and the final tree summary depends on find -printf as documented in find(1). (man7.org)

Set up a disposable workspace

Start in a clean folder so the results are easy to read and easy to remove later.

mkdir umask-lab
cd umask-lab

This keeps the experiment scoped to one directory. If you are practicing Linux permissions for everyday administration or for RHCSA Certification Training, this kind of disposable setup is safer than testing in your home directory.

Measure three different umask values

The fastest way to understand umask is to measure it instead of memorizing it. Run each case in a subshell:

(
  umask 022
  mkdir mask-022
  touch mask-022/sample.txt
  stat -c '%a %n' mask-022/sample.txt mask-022
)
(
  umask 027
  mkdir mask-027
  touch mask-027/sample.txt
  stat -c '%a %n' mask-027/sample.txt mask-027
)
(
  umask 077
  mkdir mask-077
  touch mask-077/sample.txt
  stat -c '%a %n' mask-077/sample.txt mask-077
)

Using subshells matters. umask is a process attribute, so each parenthesized block gets its own temporary mask and your interactive shell does not stay changed after the block finishes. That behavior is part of the Linux umask(2) model. The stat -c '%a %n' format prints the octal mode and the path, which is why it is better here than ls -l if you want exact numbers. umask(2) documents that the mask affects file-creation system calls, and stat(1) documents the -c formatting used to print modes cleanly. (man7.org)

The verified lab captured these creation results:

Recorded linux-umask command output

Rendered output from actual lab commands. Captured 21 October 2026, 14:02 IST. Open full-size image

That output answers the headline question directly:

  • umask 022 produced a file mode of 644 and a directory mode of 755
  • umask 027 produced 640 and 750
  • umask 077 produced 600 and 700

At this point, you have measured the behavior. The next step is to explain why those results are correct.

Do the 022 permission math explicitly

Red Hat documents two different base modes for new objects in the common case:

  • regular files start from 666
  • directories start from 777

That is why umask 022 does not produce the same result for both. Red Hat shows this directly in its RHEL 9 permissions chapter, including examples where a directory becomes 755 and a file becomes 644. (docs.redhat.com)

Regular file

0666 & ~0022 = 0644

For files, the low-level rule comes from the file-creation path documented in open(2): the created file's permissions are derived from the requested mode filtered by ~umask. In the common shell case, the starting point for a regular file is read/write for owner, group, and others, not execute. Red Hat also notes that regular files do not get execute permission by default, even with a permissive mask. (docs.redhat.com)

Directory

0777 & ~0022 = 0755

Directories start differently. mkdir(2) states that, in the absence of a default ACL, the created directory mode is filtered by the process umask. Red Hat's explanation of directory defaults shows why 755 is common: the owner keeps full access, while group and others keep read and search access so they can list and descend into the directory. (man7.org)

This is the whole trick:

  • files do not start from 777
  • directories usually do start from 777
  • the same mask clears different bits because the starting modes differ

Check the other two masks against the same rule

Once you understand the bases, the other measured values are not special cases.

With umask 027

0666 & ~0027 = 0640
0777 & ~0027 = 0750

That matches the observed lab output exactly. Group members keep read access to the file and read/search access to the directory, while others get nothing.

With umask 077

0666 & ~0077 = 0600
0777 & ~0077 = 0700

This is the private-by-default pattern many administrators want for sensitive content. The lab showed 600 for the new file and 700 for the new directory at creation time.

Prove that umask affects creation time, not later changes

Now verify the measured modes and then change one existing file on purpose:

test "$(stat -c %a mask-022/sample.txt)" = 644
test "$(stat -c %a mask-022)" = 755
test "$(stat -c %a mask-027/sample.txt)" = 640
test "$(stat -c %a mask-027)" = 750
test "$(stat -c %a mask-077/sample.txt)" = 600
test "$(stat -c %a mask-077)" = 700
chmod 644 mask-077/sample.txt
test "$(stat -c %a mask-077/sample.txt)" = 644

test returns exit status 0 when the values match and 1 when they do not; neither result prints a confirmation. The captured lab ran with set -e, so a failed check would have stopped execution before the final PASS message.

The important line is this one:

chmod 644 mask-077/sample.txt

That file was created under umask 077 as 600, but chmod changed the already existing file to 644. This is the practical distinction many learners miss:

  • umask filters the mode when an object is created
  • chmod changes the mode after the object already exists

If you inspect a real system and see a mode that does not match the current shell's umask, a later chmod or application action may be the reason.

Inspect the final tree state

Generate the exact final summary with find -printf:

find mask-022 mask-027 mask-077 -printf '%m %p\n' | tee details.txt

The verified lab recorded this final state:

Recorded linux-umask command output

Rendered output from actual lab commands. Captured 21 October 2026, 14:02 IST. Open full-size image

This output is worth reading carefully. mask-077/sample.txt appears as 644 in the final listing, even though the earlier creation output showed it was born as 600. That is not a contradiction. It proves both stages of the lab:

  1. the file was created as 600 under umask 077
  2. the file later became 644 because chmod changed it

This is exactly why measuring permissions with stat or find is better than assuming you know what happened.

One important exception: default ACLs

The simple mental model above is correct for the common case, but Linux documents an important exception. The umask(2) manual page states that if the parent directory has a default ACL, the umask is ignored for that inheritance path; the default ACL is inherited instead, and the final permissions are derived from that inherited ACL plus the mode argument. (man7.org)

So if your measured result does not match 0666 or 0777 filtered by the current mask, check in this order:

  1. what created the file or directory
  2. what umask that creating process used
  3. whether the parent directory carries a default ACL
  4. whether something later changed the mode with chmod

That troubleshooting order is much more reliable than blaming umask alone.

What to remember

The answer to the title question is precise and short:

  • new regular files usually start from 0666
  • new directories usually start from 0777
  • umask 022 clears group write and other write
  • the common results are therefore 0644 for files and 0755 for directories

Red Hat documents those defaults directly, and the lab measured them with real commands rather than theory alone. (docs.redhat.com)

Cleanup

When you are done, return to the parent directory and remove only the disposable lab folder:

cd ..
rm -rf umask-lab

That removes the directories and details.txt created by this walkthrough.

Example source files

The supporting code and configuration on GitHub contain the complete example files discussed in this article.

Sources