🚀 Supercharge your YouTube channel's growth with AI.
Try YTGrowAI FreeOS 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.
| Call | Missing parent folders | Existing directory |
|---|---|---|
| os.mkdir(path) | Does not create them | Raises FileExistsError |
| os.makedirs(path) | Creates them | Raises unless exist_ok=True |
| Path.mkdir() | Creates them with parents=True | Raises 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

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

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'

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.
| Condition | Likely symptom | Practical response |
|---|---|---|
| Target is already a directory | FileExistsError without repeat handling | Use exist_ok=True only if reuse is intended |
| Target name is a regular file | FileExistsError even with exist_ok=True | Choose another path or handle the conflict |
| Parent component is absent | FileNotFoundError from os.mkdir() | Create parents recursively or create them separately |
| Parent is not writable | PermissionError | Select a permitted destination or correct the application’s access policy |
| Relative path resolves unexpectedly | Directory appears under another base | Check os.getcwd() or use an explicit base path |
| mode does not match expected access | umask and platform affect resulting permissions | Check 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 case | What to expect | Action |
|---|---|---|
| Leaf directory mode | os.makedirs() applies mode to the leaf | Check effective permissions after creation when policy matters |
| Intermediate parents | They use default permissions filtered by umask | Do not assume the leaf mode applies to every new level |
| Different operating system | Permission behavior may vary | Test 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.
| Case | Risk | Response |
|---|---|---|
| Check path, then create it | Another process can change the target between calls | Call 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.


