Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

os.mkdir() creates exactly one directory. It succeeds only when the target name is unused and its parent already exists:

import os

os.mkdir("reports")

The function returns None. It does not create missing parent directories, create files, or accept an exist_ok argument. For nested paths or idempotent setup, use os.makedirs() or pathlib.Path.mkdir().

Syntax and core behavior

os.mkdir(path, mode=0o777, *, dir_fd=None)

The path can be a string, bytes, or a path-like object such as pathlib.Path (supported since Python 3.6). mode requests initial permission bits where the operating system supports them. dir_fd is an optional directory-descriptor-relative form for advanced code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

See the Python documentation for os.mkdir().

Create one directory

import os

os.mkdir("data")

If the call succeeds, a directory named data appears in the process’s current working directory. Check that location with:

import os

print(os.getcwd())

A relative path is relative to the current working directory, not automatically to the directory containing your Python file.

Relative and absolute paths

Relative paths

import os

print(os.getcwd())
os.mkdir("logs")

Launchers, IDEs, test runners, and services can choose different working directories. If the directory must sit beside the script, construct the path 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, doubled backslashes, or a Path:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import os
from pathlib import Path

os.mkdir(r"C:UsersAliceDocumentslogs")
os.mkdir("C:\Users\Alice\Documents\logs")
Path(r"C:UsersAliceDocumentslogs").mkdir()

Existing targets and race-safe handling

If the target already names a directory, the default behavior is an exception:

import os

os.mkdir("logs")
os.mkdir("logs")  # FileExistsError

os.mkdir() has no exist_ok parameter. When an existing directory is acceptable, handle the exception and verify the object is actually a directory:

import os

try:
    os.mkdir("logs")
except FileExistsError:
    if not os.path.isdir("logs"):
        raise

This exception-driven pattern avoids the check-then-create race in which another process creates the path after os.path.exists() has been checked. Do not assume that an existing path is harmless: a regular file, symlink, junction, or other filesystem object may occupy the name.

For ordinary “create if missing” behavior, these APIs are simpler:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Missing parent directories

os.mkdir("output/reports") fails with FileNotFoundError when output does not exist. os.mkdir() creates only the final directory entry.

import os

os.makedirs("output/reports", exist_ok=True)

The pathlib equivalent is:

from pathlib import Path

Path("output/reports").mkdir(parents=True, exist_ok=True)

Without parents=True, Path.mkdir() also raises FileNotFoundError for a missing parent. Details are in the os.makedirs() and Path.mkdir() documentation.

Understanding the mode argument

import os

os.mkdir("private_data", mode=0o700)

Octal notation expresses permission bits on POSIX systems:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • 0o700: owner can read, write, and enter; group and others have no access.
  • 0o750: owner has full access; group can read and enter; others have no access.
  • 0o755: owner has full access; group and others can read and enter.

These are requests, not guaranteed final permissions. On POSIX systems, the process’s umask removes bits from the requested mode. Some platforms ignore parts of mode. On Windows, Python 3.13 and later specially apply 0o700 as an access-control setting; other mode values are ignored according to the documentation. See the platform notes for os.mkdir().

Handling common exceptions

Exception Meaning Typical response
FileExistsError The target name is occupied Accept it only after confirming it is a directory; otherwise report the collision.
FileNotFoundError A required parent component is missing Create the tree with os.makedirs() or Path.mkdir(parents=True).
PermissionError The operating system denied creation Choose a writable parent or correct permissions and policy restrictions.
NotADirectoryError A parent component is a file Correct, rename, or remove the conflicting file.
OSError Another operating-system filesystem failure Log the path and inspect the underlying error.

A focused handler keeps expected failures understandable:

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.")

For a higher-level API, preserve the original exception context:

import os

try:
    os.mkdir("reports")
except OSError as exc:
    raise RuntimeError("Could not create reports directory") from exc

Avoid bare except:; it can hide programming errors and interrupts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choosing among directory APIs

API Best use Creates parents? Accepts existing directory?
os.mkdir() One directory, with an existing target treated as an error No No built-in option
os.makedirs() String-based nested directory trees Yes exist_ok=True
Path.mkdir() Path-oriented, object-based code parents=True exist_ok=True
tempfile.mkdtemp() Unique temporary directories Managed by the temporary-directory API Creates a new unique directory

Use os.mkdir() when a single final directory and an existing-target error are exactly what you want. Use os.makedirs() for recursive string paths. Choose Path.mkdir() when you compose, resolve, inspect, and pass paths through several operations; its documented alternatives are listed in the pathlib documentation.

Advanced: dir_fd

You can make a path relative to an open directory file descriptor:

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. Support is platform-dependent, and the parameter is mainly useful for descriptor-relative filesystem code. It was added in Python 3.3.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

User-provided paths and containment

os.mkdir() does not protect an application from absolute paths, .. traversal, symlink behavior, or writes outside an intended base directory. Resolve and validate user input before creation:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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 proper containment test such as candidate.is_relative_to(base) where available, and account for symlink and race conditions. A string-prefix test is not sufficient: /srv/my_app_backup is not inside /srv/my_app.

Verifying, removing, and testing

A successful call normally proves creation; an explicit check is useful in demonstrations or tests:

import os

path = "reports"
os.mkdir(path)
assert os.path.isdir(path)

Remove an empty directory with os.rmdir() or Path.rmdir():

import os

os.rmdir("reports")

These operations are not recursive. Recursive deletion uses shutil.rmtree() and should be reserved for deliberately validated targets because it is destructive.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For isolated tests, use a temporary directory:

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)

For application-created temporary directories, see tempfile.mkdtemp().

Production-ready patterns

One directory, existing target is an error

from pathlib import Path

output_dir = Path("output")

try:
    output_dir.mkdir()
except FileExistsError:
    if not output_dir.is_dir():
        raise

Nested, repeatable setup

from pathlib import Path

Path("output/data").mkdir(parents=True, exist_ok=True)

These two patterns make the intended policy explicit: either an existing target is noteworthy, or setup is safely repeatable.

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.