Sitelet https://www.askpython.com/python/python-directory-operations

OS mkdir: Create Directories in Python


A program may need a directory at a particular filesystem path. Python’s directory-creation calls let you create one directory or create missing parent folders along the path.

This article explains the os mkdir operation and shows how os.mkdir() and os.makedirs() create directories. It also covers common errors and permission inputs.

TL;DR: Choose the right Python directory call

Use os.mkdir() for one new directory level, and select a recursive method when parent folders may also be missing.

  • Call os.mkdir(path) when the immediate parent already exists and a duplicate target should be reported.
  • Use os.makedirs(path, exist_ok=True) or Path(path).mkdir(parents=True, exist_ok=True) when parent creation and repeat runs are expected.
  • Catch a filesystem exception only when the program can respond to that specific condition.

What is an os mkdir operation?

A mkdir operation asks the operating system to add a directory at a given path. Python exposes a one-level call, a recursive call, and a path-object method so code can match the directory layout it must create.

A path names a filesystem location. Absolute paths start at the filesystem root. Relative paths use the process current working directory as their base, even when the script file lives elsewhere.

Check os.getcwd() when a relative destination appears somewhere unexpected. A command-line value supplied by a user follows the same path rules as a string written in the program.

CallMissing parent foldersExisting directory
os.mkdir(path)Does not create themRaises FileExistsError
os.makedirs(path)Creates themRaises unless exist_ok=True
Path.mkdir()Creates them with parents=TrueRaises unless exist_ok=True

For adjacent filesystem tasks, AskPython’s guide to useful os module functions and its example of creating a directory with pathlib.

Choose based on the state your program expects, not on which spelling looks shorter. A one-off output folder under a known parent is a good fit for os.mkdir(). A cache or generated report tree often needs parent creation and repeat handling, so the recursive form expresses that requirement in the operation itself.

The table compares creation behavior and omits details outside this choice. Each method accepts a path-like object. Filesystem permissions and available storage still govern the result, and neither method can turn a file into a folder.

How to create directories with Python step by step

Start with the path shape and the state the program should accept. The following examples distinguish one-level creation, nested creation, and repeat-safe behavior.

Step 1: Create one directory with os.mkdir()

os.mkdir() is the direct choice when the parent exists and the final directory should be new. The temporary parent below keeps the example self-contained and removes its test directory when the context ends.

from pathlib import Path
import os
import tempfile

with tempfile.TemporaryDirectory(prefix="os-mkdir-", dir=".") as temp_dir:
    target = Path(temp_dir) / "reports"
    os.mkdir(target)
    print("created:", target.is_dir())

I ran python3 mkdir_single_demo.py. The check printed the following result:

created: True
Terminal output showing os.mkdir created a directory
The terminal shows the directory check returning True.

The Path object works anywhere these filesystem functions accept a path string. TemporaryDirectory prepares the parent first, isolating the one-level behavior.

A name already attached to a directory raises FileExistsError. That can flag an unexpected collision instead of treating it as success.

Keep the parent stable when building a path from configuration. For a relative destination, print or log the current working directory during diagnosis, then decide whether the program should use an absolute base. Avoid changing the process working directory as an implicit fix, since that affects every relative filesystem operation performed later in the process.

Step 2: Create nested directories with os.makedirs()

Choose os.makedirs() when several components in the destination may be absent. With exist_ok=True, an existing directory at the final target is accepted, which makes a repeat run safe for that case.

from pathlib import Path
import os
import tempfile

with tempfile.TemporaryDirectory(prefix="os-makedirs-", dir=".") as temp_dir:
    root = Path(temp_dir)
    nested = root / "archive" / "2026"
    os.makedirs(nested, exist_ok=True)
    os.makedirs(nested, exist_ok=True)
    print("os.makedirs nested:", nested.is_dir())
    print("os.makedirs repeated:", nested.is_dir())
    daily = root / "logs" / "daily"
    daily.mkdir(parents=True, exist_ok=True)
    print("Path.mkdir parents:", daily.is_dir())

I ran python3 mkdir_nested_demo.py. All three checks printed True:

os.makedirs nested: True
os.makedirs repeated: True
Path.mkdir parents: True
Terminal output showing recursive os.makedirs and Path.mkdir checks
The output compares nested creation and repeat calls for both recursive APIs.

Path.mkdir() uses method arguments, which keeps the call within pathlib code that already represents locations as Path objects.

Path.mkdir() defaults parents and exist_ok to False. Setting parents=True creates missing ancestors, while exist_ok controls whether the target directory may already exist.

os.makedirs() provides the recursive operation for code that already uses os.path or passes strings to filesystem functions.

For a file-writing workflow, create the parent directory before opening the output file. Creating the directory does not create the file, and a missing parent causes its own filesystem error. Handle a file conflict separately from an existing folder because the application may need different recovery behavior.

Step 3: Create a directory at a chosen path

Path.home() / “project-output” forms the base for this destination. The selected directory may differ on another system because home locations are account-specific. This example uses pathlib to combine path components before calling mkdir().

The trailing components can represent a date, a batch identifier, or another output category chosen by the program. Creating the parent tree before writing files keeps directory setup separate from serialization and file naming. If the target is already present, choose reuse or conflict handling based on whether previous output should remain.

Building a destination from smaller components also helps when the final folder name depends on a user option. Keep the base directory separate from that option, then validate the resulting location against the program’s rules. This division makes it simpler to test path selection without writing files into the destination.

Change the base to a directory appropriate for the application. Path.home() selects the current user’s home directory, while a relative Path starts under the working directory described above.

A supplied base can make path behavior clear when the program runs from different launch locations. In a command-line utility, resolve the option against a documented base rather than assuming the shell is in the project folder. That keeps the chosen destination tied to the interface the user was given.

Separate the stable base from variable output components such as a report name or date. This makes it clear which part of a destination comes from configuration and which part the program generates. It also gives tests a way to substitute a temporary base without changing the path-building logic.

Absolute paths are useful for scheduled jobs whose working directory may vary between interactive and automated execution. A configured base also lets tests isolate output from the user’s home directory. Set that base to a temporary test location, then append the report or date components needed by the test.

Python directory creation errors and edge cases

Filesystem exceptions report whether the target exists, a parent is missing, or access is denied.

Step 4: Read existing-file and missing-parent errors

This example catches two expected failures and prints the exception messages. The cleanup runs even if an unexpected error occurs during the demonstration.

from pathlib import Path
import os
import shutil

DEMO_ROOT = Path(".directory-errors-demo")
DEMO_ROOT.mkdir()

try:
    file_target = DEMO_ROOT / "not-a-directory"
    file_target.write_text("occupied", encoding="utf-8")
    try:
        os.makedirs(file_target, exist_ok=True)
    except FileExistsError as error:
        print(f"existing file: {type(error).__name__}: {error}")

    missing_parent = DEMO_ROOT / "missing-parent" / "child"
    try:
        os.mkdir(missing_parent)
    except FileNotFoundError as error:
        print(f"missing parent: {type(error).__name__}: {error}")
finally:
    shutil.rmtree(DEMO_ROOT)

I ran python3 mkdir_errors_demo.py. It reported both filesystem conditions:

existing file: FileExistsError: [Errno 17] File exists: '.directory-errors-demo/not-a-directory'
missing parent: FileNotFoundError: [Errno 2] No such file or directory: '.directory-errors-demo/missing-parent/child'
Terminal output with FileExistsError and FileNotFoundError
The output shows separate errors for a file target and an absent parent.

FileExistsError means a filesystem entry already occupies the requested name, but it may be a regular file rather than a directory. FileNotFoundError from the single-level call points to a missing component above the final target.

ConditionLikely symptomPractical response
Target is already a directoryFileExistsError without repeat handlingUse exist_ok=True only if reuse is intended
Target name is a regular fileFileExistsError even with exist_ok=TrueChoose another path or handle the conflict
Parent component is absentFileNotFoundError from os.mkdir()Create parents recursively or create them separately
Parent is not writablePermissionErrorSelect a permitted destination or correct the application’s access policy
Relative path resolves unexpectedlyDirectory appears under another baseCheck os.getcwd() or use an explicit base path
mode does not match expected accessumask and platform affect resulting permissionsCheck the deployment permission policy

For PermissionError, select a destination the process may write to or follow the application’s access policy. Avoid a broad OSError handler when the program cannot recover from other filesystem failures.

For a command-line utility, report the conflicting path so the user can choose another destination. A background job may instead log the path and stop that job while leaving its input intact. In either case, make the recovery specific to the condition rather than deleting or overwriting an entry as an automatic response.

Treat mode and umask as permission inputs

The mode argument is subject to umask and platform behavior.

Mode caseWhat to expectAction
Leaf directory modeos.makedirs() applies mode to the leafCheck effective permissions after creation when policy matters
Intermediate parentsThey use default permissions filtered by umaskDo not assume the leaf mode applies to every new level
Different operating systemPermission behavior may varyTest the application’s access policy on its deployment platform

Avoid a check-then-create race

Checking whether a path exists and creating it in a later statement leaves time for another process to change the filesystem. The directory may appear between those operations, so the check does not guarantee that the subsequent creation succeeds.

CaseRiskResponse
Check path, then create itAnother process can change the target between callsCall mkdir with the intended parents and exist_ok settings directly

When concurrent jobs share a cache or export destination, decide whether reuse is acceptable before setting exist_ok=True. It does not clear the directory or inspect its contents, so a job may need to verify ownership before writing there.

Conclusion

Choose the call that matches the directory layout and the program’s response to an existing target. Keeping those two choices explicit makes directory setup clearer to review.

Consult the Python documentation for os.mkdir(), os.makedirs(), and Path.mkdir() for argument and platform details.

FAQ

These answers address the common choices around Python directory creation.

How do I use os.mkdir() in Python?

Pass the path of one new directory to os.mkdir(). Its parent must exist. Use os.makedirs() or Path.mkdir(parents=True) when parent folders also need to be created.

How do I create a directory with pathlib?

Create a Path for the destination and call mkdir(). Set parents=True for missing parent folders and exist_ok=True when an existing directory should be accepted.

Why does exist_ok=True still raise FileExistsError?

That option permits an existing directory at the target. A regular file at the same path is still a conflict and raises FileExistsError.

Pankaj Kumar
Pankaj Kumar

I have been working on Python programming for more than 12 years. At AskPython, I share my learning on Python with other fellow developers.

Articles: 261