Fix: Python FileNotFoundError: [Errno 2] No such file or directory
Quick Answer
How to fix Python FileNotFoundError No such file or directory caused by relative vs absolute paths, wrong working directory, missing files, pathlib usage, and Docker container file access.
The Error
You run a Python script and get:
Traceback (most recent call last):
File "app.py", line 3, in <module>
with open("config.json") as f:
FileNotFoundError: [Errno 2] No such file or directory: 'config.json'Or variations:
FileNotFoundError: [Errno 2] No such file or directory: 'data/input.csv'FileNotFoundError: [Errno 2] No such file or directory: '/home/user/project/output.txt'Python tried to open a file that does not exist at the specified path. The file either doesn’t exist, exists at a different location, or the path is wrong.
Why This Happens
When you call open("config.json") with a relative path, Python looks for the file relative to the current working directory — not relative to the script’s location. These are often different.
If you run python app.py from /home/user/, Python looks for /home/user/config.json. But if config.json is in /home/user/project/, it won’t be found.
Common causes:
- Relative path resolved from the wrong directory. You ran the script from a different directory than expected.
- The file genuinely doesn’t exist. A typo in the filename, it was never created, or it was deleted.
- IDE sets a different working directory. VS Code, PyCharm, and other IDEs may set the working directory to the project root, which differs from running in the terminal.
- Path separator issues on Windows. Backslashes in paths need escaping or should use forward slashes.
- File is in a Docker container but the path points to the host filesystem.
Fix 1: Use Absolute Paths Relative to the Script
The most reliable fix. Construct paths relative to the script file, not the working directory:
from pathlib import Path
# Get the directory where this script lives
script_dir = Path(__file__).parent
# Build paths relative to the script
config_path = script_dir / "config.json"
data_path = script_dir / "data" / "input.csv"
with open(config_path) as f:
config = json.load(f)Path(__file__).parent always returns the directory containing the current Python file, regardless of where you run it from.
The older os.path equivalent:
import os
script_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(script_dir, "config.json")Pro Tip: Use
pathlib.Pathinstead ofos.pathfor new code. It provides a cleaner API with/operator for path joining, and methods like.exists(),.read_text(), and.mkdir()built in.
Fix 2: Check Your Working Directory
If you use relative paths, verify where Python thinks you are:
import os
print(os.getcwd())This prints the current working directory. If it is different from where your file is, that explains the error.
Fix from the terminal:
cd /path/to/project
python app.pyFix in VS Code:
Add to .vscode/settings.json:
{
"python.terminal.executeInFileDir": true
}Or in launch.json:
{
"cwd": "${fileDirname}"
}Fix in PyCharm:
Go to Run → Edit Configurations → Working directory, and set it to your project root.
Fix 3: Check if the File Exists Before Opening
Add a check to give a clearer error message:
from pathlib import Path
filepath = Path("data/input.csv")
if not filepath.exists():
print(f"File not found: {filepath.absolute()}")
print(f"Current directory: {Path.cwd()}")
print(f"Files in directory: {list(Path.cwd().iterdir())}")
raise SystemExit(1)
with open(filepath) as f:
data = f.read()This prints the absolute path Python is trying to access and lists the files in the current directory, making debugging much easier.
Fix 4: Handle Windows Path Issues
Windows uses backslashes (\) in paths, which are escape characters in Python strings:
# WRONG — \n is a newline, \t is a tab
path = "C:\Users\name\test\new_file.txt"
# RIGHT — use raw strings
path = r"C:\Users\name\test\new_file.txt"
# RIGHT — use forward slashes (works on Windows)
path = "C:/Users/name/test/new_file.txt"
# BEST — use pathlib
path = Path("C:/Users/name/test/new_file.txt")Common Mistake: Using backslashes in Python path strings without the
rprefix.\n,\t,\r, and\bare all escape sequences. The path"C:\new\test\data"becomes"C:<newline>ew<tab>est<backspace>ata". Always use raw strings (r"...") or forward slashes on Windows.
Fix 5: Create Missing Directories
If the error is about the directory not existing (not just the file):
FileNotFoundError: [Errno 2] No such file or directory: 'output/results/data.csv'The output/results/ directory might not exist. Create it first:
from pathlib import Path
output_path = Path("output/results/data.csv")
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, "w") as f:
f.write("data")parents=True creates all intermediate directories. exist_ok=True doesn’t error if the directory already exists.
Fix 6: Fix Paths in Docker Containers
Inside a Docker container, the filesystem is different from your host machine. A path like /home/user/project/data.csv doesn’t exist in the container.
Fix: Mount the data directory as a volume:
docker run -v /host/path/to/data:/app/data myimageThen in your Python code, use the container path:
with open("/app/data/input.csv") as f:
data = f.read()In Docker Compose:
services:
app:
build: .
volumes:
- ./data:/app/dataMake sure the Dockerfile sets the correct working directory:
WORKDIR /app
COPY . .Fix 7: Handle subprocess FileNotFoundError
If the error comes from subprocess:
import subprocess
result = subprocess.run(["my-tool", "--version"], capture_output=True)
# FileNotFoundError: [Errno 2] No such file or directory: 'my-tool'This means the executable my-tool is not found in PATH.
Fix: Use the full path to the executable:
result = subprocess.run(["/usr/local/bin/my-tool", "--version"], capture_output=True)Or check if it exists first:
import shutil
if shutil.which("my-tool") is None:
print("my-tool is not installed or not in PATH")
else:
subprocess.run(["my-tool", "--version"])On Windows, you might need to add .exe:
subprocess.run(["my-tool.exe", "--version"])If Python itself isn’t found, see Fix: python command not found.
Fix 8: Use pathlib for Robust Path Handling
pathlib handles cross-platform path differences automatically:
from pathlib import Path
# Works on Linux, macOS, and Windows
base = Path(__file__).parent
config = base / "config" / "settings.json"
data = base / "data" / "input.csv"
# Check existence
if config.is_file():
content = config.read_text()
# List files in a directory
for f in (base / "data").glob("*.csv"):
print(f.name)
# Create directories
(base / "output").mkdir(exist_ok=True)Key pathlib methods:
| Method | What it does |
|---|---|
Path.exists() | Check if path exists |
Path.is_file() | Check if it’s a file |
Path.is_dir() | Check if it’s a directory |
Path.read_text() | Read file contents |
Path.write_text() | Write text to file |
Path.mkdir() | Create directory |
Path.glob() | Find files matching pattern |
Path.resolve() | Get absolute path |
Path.parent | Get parent directory |
Still Not Working?
If the file definitely exists but Python still can’t find it:
Check for invisible characters in the filename. Copy-pasting filenames from web pages or documents can introduce zero-width spaces or non-breaking spaces:
import os
for f in os.listdir("."):
print(repr(f)) # Shows hidden charactersCheck for symbolic links. A symlink might point to a target that was moved or deleted:
ls -la filenameCheck file encoding in the filename. Non-ASCII characters (accents, CJK characters) in filenames can cause issues on some systems. Rename the file to use only ASCII characters.
Check for race conditions. In multithreaded code, one thread might delete a file between another thread’s existence check and open call. Use try/except:
try:
with open(filepath) as f:
data = f.read()
except FileNotFoundError:
print(f"{filepath} was deleted or moved")Check for permission issues masquerading as FileNotFoundError. In rare cases, missing execute permission on a parent directory causes FileNotFoundError instead of PermissionError. Check parent directory permissions. For permission-related issues, see Fix: Python PermissionError.
Check for Python’s module not found. If the error is about importing a module (not opening a file), you have a different issue. See Fix: ModuleNotFoundError instead.
If the error occurs specifically with an import statement and you see a traceback mentioning IndentationError, the file might exist but have syntax errors that prevent loading.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: AWS Lambda Unable to import module / Runtime.ImportModuleError
How to fix the AWS Lambda Runtime.ImportModuleError and Unable to import module error caused by wrong handler paths, missing dependencies, layer issues, and packaging problems.
Fix: Python TypeError: unhashable type: 'list'
Learn why Python raises TypeError unhashable type list, dict, or set and how to fix it when using dictionary keys, sets, groupby, dataclasses, and custom classes.
Fix: Django Forbidden (403) CSRF verification failed
How to fix Django 403 CSRF verification failed error caused by missing CSRF tokens, AJAX requests, cross-origin issues, HTTPS misconfig, and session problems.
Fix: FastAPI 422 Unprocessable Entity (validation error)
How to fix FastAPI 422 Unprocessable Entity error caused by wrong request body format, missing fields, type mismatches, query parameter errors, and Pydantic validation.