Python Create Directory Recursively

Learn how to create directories recursively in Python using pathlib Path.mkdir(parents=True, exist_ok=True) and os.makedirs(), including create-if-not-exists examples and common errors.

Published

Updated

Read time 6 min read

Reviewed byDeepak Prasad

Python Create Directory Recursively

If you need a folder tree such as data/reports/2026 before writing logs or exports, Python’s standard library gives you two solid tools: pathlib.Path.mkdir (usually preferred) and os.makedirs. This page puts pathlib first, matches the official Path.mkdir signature (parents, exist_ok), then covers os.makedirs, comparisons, creating parents before saving a file, errors, and why distutils is obsolete.

Examples use relative paths like data/reports/2026 and, where a full path helps, Path.home() / "reports" so the ideas work on Windows and Linux. Each fenced example is a complete script (imports included) that creates directories under tempfile.TemporaryDirectory() so it does not touch your project tree. Those operations are file system I/O: the opening fences use {run=false} so the in-page Run control is not offered on Cloudflare Pages (Judge0 may block or vary temp filesystem behavior). Copy the snippet into a local python3 shell or script for the same output.

Tested on: Python 3.13.3; kernel 6.14.0-37-generic.


Best way to create directories recursively in Python

Use pathlib.Path with parents=True (create missing parents) and exist_ok=True (do not fail if the leaf directory already exists):

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    path = Path(tmp) / "logs" / "2026" / "06"
    path.mkdir(parents=True, exist_ok=True)
    print(path.is_dir())

You should see True: the whole chain logs/2026/06 exists under the temp root. That pattern maps directly to project code such as Path("data/reports/2026") when tmp is your working tree.


Create nested directories using pathlib Path.mkdir()

Path.mkdir follows mkdir(mode=0o777, parents=False, exist_ok=False) in the docs. For nested trees you almost always want parents=True. Use mode= only when you care about permission bits on POSIX; on Windows it may be partially ignored.

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    nested = Path(tmp) / "data" / "reports" / "2026"
    nested.mkdir(parents=True, exist_ok=False)
    print(nested)

Running it prints an absolute path ending in .../data/reports/2026. A second run with the same path and exist_ok=False would raise FileExistsError unless you set exist_ok=True.


Create directory if it does not exist using pathlib

Set exist_ok=True when rerunning scripts or tests should not crash if the directory is already there. The docs note that exist_ok=True does not help if a file already sits where you want a directory—you still get FileExistsError. See check if a path exists before creating when you expect collisions.

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    path = Path(tmp) / "cache" / "session"
    path.mkdir(parents=True, exist_ok=True)
    path.mkdir(parents=True, exist_ok=True)
    print("ok", path.is_dir())

You should see ok True twice in spirit—the second mkdir is a no-op for an existing directory.


Create nested directories using os.makedirs()

os.makedirs creates the leaf directory and any intermediate ones. With exist_ok=False (the default), an existing target directory raises FileExistsError.

python
import os
import tempfile

with tempfile.TemporaryDirectory() as tmp:
    target = os.path.join(tmp, "logs", "2026", "06")
    os.makedirs(target, exist_ok=True)
    print(os.path.isdir(target))

You should see True. Prefer os.path.join (or pathlib) over hardcoding \ or / so the same code runs cross-platform.


Create directory if it does not exist using os.makedirs

Pass exist_ok=True for idempotent setup, the same idea as Path.mkdir(..., exist_ok=True).

python
import os
import tempfile

with tempfile.TemporaryDirectory() as tmp:
    target = os.path.join(tmp, "out", "render")
    os.makedirs(target, exist_ok=True)
    os.makedirs(target, exist_ok=True)
    print("ready")

This prints ready without error. If a file named render already exists, both APIs fail with FileExistsError when you try to create a directory at that path.


pathlib mkdir vs os.makedirs

Path.mkdir(parents=True, exist_ok=True) os.makedirs(..., exist_ok=True)
Style Object-oriented Path objects String paths with os
Typical use New application code, composition with read_text / write_text Legacy scripts, glue next to other os.* calls
Parents parents=True Always recursive for the full path
Existence exist_ok=True exist_ok=True (Python 3.2+)

Pick one style per module for consistency; mixing is fine at boundaries if you convert with Path(p) or os.fspath(p).


Create parent folders before writing a file

Real code often needs the parent of a file path, not the file itself:

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    file_path = Path(tmp) / "reports" / "2026" / "june" / "output.txt"
    file_path.parent.mkdir(parents=True, exist_ok=True)
    file_path.write_text("Report generated")
    print(file_path.read_text())

You should see Report generated. On user-owned trees you can build under the home directory without hardcoding separators, for example Path.home() / "reports" / "2026" (same mkdir on .parent before writing).


Handle errors while creating directories

Catch PermissionError when the process lacks rights, and OSError for other platform issues (disk full, read-only filesystem, invalid name).

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    path = Path(tmp) / "logs" / "2026" / "06"
    try:
        path.mkdir(parents=True, exist_ok=True)
        print("created", path.is_dir())
    except PermissionError:
        print("Permission denied")
    except OSError as error:
        print(f"Could not create directory: {error}")

In normal temp setups this prints created True. For more on failures when opening paths, see FileNotFoundError in Python.


Why distutils.dir_util.mkpath should be avoided

Older tutorials used distutils.dir_util.mkpath(). distutils was removed from the standard library in Python 3.12 (deprecated earlier in 3.10). Do not teach it as a current option; use pathlib.Path.mkdir or os.makedirs instead and migrate any legacy mkpath call sites.


Common mistakes when creating directories

  • Omitting parents=True and then wondering why a nested path raises FileNotFoundError because an intermediate folder is missing.
  • Omitting exist_ok=True in idempotent jobs so reruns raise FileExistsError even though the tree is already correct.
  • Importing or copying distutils examples into a Python 3.12+ environment where the module is gone.
  • Calling mkdir on a path where a file already exists with the same name—both pathlib and os refuse to replace a file with a directory via these calls.
  • Hardcoding C:\... or mixing / and \ by hand; prefer Path(...) or os.path.join.
  • Opening Path("reports/june.txt") for write without creating Path("reports") first—create .parent (or use open helpers that document who creates parents).
  • Swallowing all errors: at minimum distinguish PermissionError from other OSError types so operators can react.

Python create directory quick reference table

Need Approach
Recursive create (modern) Path("a/b/c").mkdir(parents=True, exist_ok=True)
Recursive create (os) os.makedirs(os.path.join("a", "b", "c"), exist_ok=True)
Parents only for a file file_path.parent.mkdir(parents=True, exist_ok=True)
Default “fail if exists” omit exist_ok or pass False
Sum of permission details on POSIX set mode= on mkdir where documented

Summary

For recursive directory creation in current Python, start with pathlib.Path.mkdir(parents=True, exist_ok=True); use os.makedirs(..., exist_ok=True) when string paths and the os module fit your codebase. Create parent directories before writing files with file_path.parent.mkdir(...). Handle PermissionError and OSError, and do not rely on distutils—it is gone from the stdlib in 3.12+. For writing after the tree exists, follow up with write to file patterns in your app.


References


Frequently Asked Questions

1. What is the best way to create nested directories in Python?

Prefer pathlib.Path.mkdir(parents=True, exist_ok=True) for new code; use os.makedirs(path, exist_ok=True) when you already work with str paths in os-heavy code.

2. What does parents=True do in Path.mkdir?

It creates any missing parent directories along the path; without it, a missing parent raises FileNotFoundError.

3. What does exist_ok=True do for mkdir and makedirs?

If the target directory already exists, no error is raised; if a file exists at the same path, you still get FileExistsError.

4. Why should I avoid distutils.dir_util.mkpath?

distutils was removed from the standard library in Python 3.12; use pathlib or os.makedirs instead.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …