The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →os.mkdir() creates exactly one new directory. Its parent must already exist, and the target path must not be occupied. The basic call is:
import os
os.mkdir("reports")
On success, the function returns None. For nested paths or an existing-directory-safe operation, use os.makedirs() or pathlib.Path.mkdir() instead.
Syntax and behavior
The documented signature is os.mkdir(path, mode=0o777, *, dir_fd=None).
pathis the directory name or path to create. Strings, bytes, and path-like objects such aspathlib.Pathare accepted.moderequests permission bits on platforms that support them.dir_fdoptionally makes a relative path resolve from an open directory file descriptor.
os.mkdir() does not create files, add content, or create missing parent directories.
#1 Best Overall
Creating a directory with a relative or absolute path
Relative paths
A relative path is interpreted from the process’s current working directory, not automatically from the directory containing your Python file.
import os
print(os.getcwd())
os.mkdir("logs")
If the program is launched from a different directory, logs will be created there. To create a directory beside the script, use its resolved location explicitly:
from pathlib import Path
project_root = Path(__file__).resolve().parent
logs_dir = project_root / "logs"
logs_dir.mkdir()
Absolute paths
import os
os.mkdir("/tmp/my_app_logs")
On Windows, avoid unescaped backslashes. Use a raw string, escaped backslashes, or a Path:
import os
os.mkdir(r"C:UsersAliceDocumentslogs")
os.mkdir("C:\Users\Alice\Documents\logs")
from pathlib import Path
Path(r"C:UsersAliceDocumentslogs").mkdir()
What happens when the target already exists?
The second call below raises FileExistsError:
import os
os.mkdir("logs")
os.mkdir("logs")
os.mkdir() has no exist_ok parameter. If an existing directory is acceptable, use an API that supports that policy:
Recommended Free Tools
import os
os.makedirs("logs", exist_ok=True)
from pathlib import Path
Path("logs").mkdir(exist_ok=True)
exist_ok=True accepts an existing directory, not an existing regular file or other incompatible filesystem object.
Rank #2
For a single-directory operation that must tolerate an existing directory while rejecting a file collision:
import os
try:
os.mkdir("logs")
except FileExistsError:
if not os.path.isdir("logs"):
raise
A check followed by creation, such as if not os.path.exists(...): os.mkdir(...), is race-prone: another process can create the path between those two operations.
Creating nested directories
os.mkdir("output/reports") fails with FileNotFoundError when output does not already exist. Use os.makedirs() for a directory tree:
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallimport os
os.makedirs("output/2026/august", exist_ok=True)
The exist_ok=True option makes the operation idempotent when the complete path is already a directory.
The equivalent object-oriented form is:
from pathlib import Path
Path("output/2026/august").mkdir(parents=True, exist_ok=True)
Without parents=True, Path.mkdir() also raises FileNotFoundError when a parent is missing.
Understanding the mode argument
import os
os.mkdir("private_data", mode=0o700)
On POSIX systems, the requested mode is combined with the process’s umask, so 0o777 is not necessarily the final permission set. The final three octal digits represent owner, group, and other permissions:
| Mode | Typical POSIX meaning |
|---|---|
0o700 |
Owner can read, write, and enter; group and others have no access. |
0o755 |
Owner has full access; group and others can read and enter. |
0o750 |
Owner has full access; group can read and enter; others have no access. |
Permission semantics are platform-dependent. Some systems ignore parts of mode. On Windows, Python 3.13 and later specifically apply 0o700 as an access-control setting for a new directory; other mode values are ignored according to the Python documentation. Do not assume that 0o700 produces identical behavior everywhere.
Handling common exceptions
| Exception | Meaning | Typical response |
|---|---|---|
FileExistsError |
The target is already occupied. | Accept it only if it is a directory; otherwise report the collision. |
FileNotFoundError |
A required parent component is missing. | Create the parent tree with os.makedirs() or Path.mkdir(parents=True). |
PermissionError |
The operating system denied the operation. | Choose a writable location or correct the applicable permissions and policy. |
NotADirectoryError |
A parent component is a regular file. | Correct, rename, or remove the conflicting path. |
OSError |
Another operating-system filesystem failure occurred. | Inspect the original error and the path involved. |
import os
directory = "reports"
try:
os.mkdir(directory)
except FileExistsError:
if not os.path.isdir(directory):
raise
print(f"{directory!r} already exists.")
except FileNotFoundError:
print("The parent directory does not exist.")
except PermissionError:
print("Permission denied.")
Avoid a bare except:; it can hide interrupts and programming errors. When adding application context, preserve the original exception:
import os
try:
os.mkdir("reports")
except OSError as exc:
raise RuntimeError("Could not create reports directory") from exc
Advanced: creating relative to a directory descriptor
dir_fd is optional and platform-dependent. It is useful when low-level code needs filesystem operations relative to an already opened directory:
import os
parent_fd = os.open("workspace", os.O_RDONLY)
try:
os.mkdir("cache", dir_fd=parent_fd)
finally:
os.close(parent_fd)
This creates cache inside the directory represented by parent_fd. The parameter was added in Python 3.3 and is not needed for ordinary scripts.
Choosing among directory APIs
| API | Best fit | Creates missing parents? | Existing-target option |
|---|---|---|---|
os.mkdir() |
One directory, with an existing target treated as an error. | No | No exist_ok parameter |
os.makedirs() |
String-based nested directory trees. | Yes | exist_ok=True |
Path.mkdir() |
Path-heavy, object-oriented code. | With parents=True |
exist_ok=True |
tempfile.mkdtemp() |
Unique temporary directories. | Creates a temporary directory | Designed to avoid name collisions |
Use os.mkdir() when the parent is guaranteed to exist and the direct operating-system primitive is what you need. Prefer os.makedirs() for recursive string paths and Path.mkdir() when paths are composed, resolved, and inspected throughout the program. For temporary work, use tempfile.mkdtemp() rather than a predictable hand-built name.
Production patterns and verification
Single directory with an explicit collision policy
from pathlib import Path
output_dir = Path("output")
try:
output_dir.mkdir()
except FileExistsError:
if not output_dir.is_dir():
raise
Idempotent nested setup
from pathlib import Path
data_dir = Path("project") / "data" / "raw"
data_dir.mkdir(parents=True, exist_ok=True)
Successful completion without an exception is normally sufficient evidence that creation worked. In demonstrations or tests, verify explicitly:
import os
import tempfile
with tempfile.TemporaryDirectory() as temp_dir:
target = os.path.join(temp_dir, "test")
os.mkdir(target)
assert os.path.isdir(target)
Path safety with user input
The API itself does not prevent absolute paths, .. traversal, symlink surprises, or creation outside an intended base directory. Resolve and validate user-controlled paths before creating them:
from pathlib import Path
base = Path("/srv/my_app").resolve()
candidate = (base / user_supplied_name).resolve()
if candidate.parent != base:
raise ValueError("Invalid directory name")
candidate.mkdir()
For nested user-controlled paths, use a containment test such as candidate.is_relative_to(base) where supported, and account for symlink and race conditions. A string prefix test is not sufficient: /srv/my_app_backup is not inside /srv/my_app.
Removing a directory
os.rmdir() removes an empty directory:
import os
os.rmdir("reports")
It is not recursive. Removing a non-empty directory requires shutil.rmtree(), which permanently deletes a directory tree and should be used only after carefully validating the target.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
Frequently Asked Questions
Does os.mkdir() create parent directories?
No. It creates only the final directory. Use os.makedirs(path, exist_ok=True) or Path(path).mkdir(parents=True, exist_ok=True) for missing parents.
How do I avoid FileExistsError?
Use os.makedirs(…, exist_ok=True) or Path.mkdir(exist_ok=True) when an existing directory is acceptable. Neither treats an existing regular file as a directory.
Why was the directory created in the wrong location?
Relative paths use the process’s current working directory. Inspect it with os.getcwd(), or build a path from Path(__file__).resolve().parent.
How do I create a temporary directory?
Use tempfile.mkdtemp(), which is intended to produce a uniquely named temporary directory.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

