FileExistsError: [Errno 17] File exists (tested)

FileExistsError: [Errno 17] File exists means Python was asked to create a directory, file or link at a path that is already taken. We measured the usual sources on Python 3.13.5, including the case where exist_ok=True doesn't help.

1. os.mkdir on a directory that exists

import os
os.mkdir("out")
try:
    os.mkdir("out")
except FileExistsError as e:
    print(type(e).__name__, e)
os.makedirs("out/a/b", exist_ok=True)
os.makedirs("out/a/b", exist_ok=True)          # no error the second time
print("makedirs exist_ok: fine")
from pathlib import Path
Path("out/c").mkdir(parents=True, exist_ok=True)
Path("out/c").mkdir(parents=True, exist_ok=True)
print("Path.mkdir exist_ok: fine")

Output:

FileExistsError [Errno 17] File exists: 'out'
makedirs exist_ok: fine
Path.mkdir exist_ok: fine

Measured on Python 3.13.5: os.mkdir raises FileExistsError: [Errno 17] File exists the second time. os.makedirs(path, exist_ok=True) and Path(path).mkdir(parents=True, exist_ok=True) create any missing parents and do nothing if the directory is already there.

2. exist_ok=True still fails if a file has that name

import os
open("logs", "w").close()                     # a FILE named logs already exists
try:
    os.makedirs("logs", exist_ok=True)
except FileExistsError as e:
    print("exist_ok but it's a file:", e)

Output:

exist_ok but it's a file: [Errno 17] File exists: 'logs'

Measured: exist_ok only forgives an existing directory. If a regular file sits at that path (a log file called logs, a download that saved as output with no extension), you still get Errno 17. Rename or remove the file, or pick a different directory name.

3. Don't check first: use exist_ok, or mode "x" to claim a file

import os
# check-then-create is a race: another process can create it in between
if not os.path.exists("data"):
    os.mkdir("data")
# open(..., "x") fails if the file exists: use it to claim a file atomically
with open("data/lock", "x") as f:
    f.write("mine")
try:
    open("data/lock", "x")
except FileExistsError as e:
    print("mode 'x':", e)

Output:

mode 'x': [Errno 17] File exists: 'data/lock'

"if not exists: mkdir" is a race: with parallel workers, two can pass the check and the second mkdir fails. exist_ok=True has no gap. For files, open(path, "x") creates the file only if it doesn't exist and raises FileExistsError otherwise, which makes it a simple lock or "write once" guard.

4. symlink, copytree, rename

import os, shutil
open("a.txt", "w").write("new")
open("b.txt", "w").write("old")
os.replace("a.txt", "b.txt")                  # overwrites on every OS
print("os.replace:", open("b.txt").read())
os.symlink("b.txt", "link")
try:
    os.symlink("b.txt", "link")
except FileExistsError as e:
    print("symlink:", e)
shutil.copytree("out", "copy")
try:
    shutil.copytree("out", "copy")
except FileExistsError as e:
    print("copytree:", e)
shutil.copytree("out", "copy", dirs_exist_ok=True)
print("copytree dirs_exist_ok: fine")

Output:

os.replace: new
symlink: [Errno 17] File exists: 'b.txt' -> 'link'
copytree: [Errno 17] File exists: 'copy'
copytree dirs_exist_ok: fine

Measured on Linux: os.replace overwrites the destination; os.symlink and shutil.copytree refuse an existing target. copytree(..., dirs_exist_ok=True) (3.8+) merges into the existing directory. On Windows (not tested here), os.rename also raises FileExistsError if the destination exists ([WinError 183]), per the docs; use os.replace when you mean "overwrite".

Frequently asked questions

What does FileExistsError: [Errno 17] File exists mean?

You asked Python to create something at a path that is already taken: os.mkdir on an existing directory, open(path, 'x'), os.symlink or shutil.copytree onto an existing target. We measured each on Python 3.13.5.

How do I create a directory only if it doesn't exist in Python?

os.makedirs(path, exist_ok=True) or Path(path).mkdir(parents=True, exist_ok=True). We measured both succeeding when run twice.

Why do I get FileExistsError even with exist_ok=True?

A regular file, not a directory, exists at that path. We measured makedirs('logs', exist_ok=True) failing because a file named logs existed.

How do I fix FileExistsError in shutil.copytree?

Pass dirs_exist_ok=True (Python 3.8+) to copy into an existing directory. We measured it succeed where the plain call raised Errno 17.

How do I rename a file and overwrite the destination?

Use os.replace, which overwrites on every OS. We measured it replacing an existing file; os.rename raises FileExistsError on Windows when the target exists.

Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5 on Linux: os.mkdir twice, makedirs and Path.mkdir with exist_ok, exist_ok over a regular file, open mode 'x', os.replace, os.symlink and shutil.copytree with and without dirs_exist_ok. Every block was run verbatim and its output pasted from that run. Windows was not tested; the os.rename note is from the Python docs. PlainHeaders is our extension; everything else here is built-in Python.