Fix: Python PermissionError: [Errno 13] Permission denied
Quick Answer
How to fix Python PermissionError Errno 13 Permission denied when reading, writing, or executing files, covering file permissions, ownership, virtual environments, Windows locks, and SELinux.
The Error
You run a Python script and get:
Traceback (most recent call last):
File "app.py", line 5, in <module>
with open("/var/log/myapp.log", "w") as f:
PermissionError: [Errno 13] Permission denied: '/var/log/myapp.log'Or variations like:
PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.12/site-packages/somepackage'PermissionError: [Errno 13] Permission denied: 'output.csv'Python tried to access a file or directory and the operating system refused. Your user account does not have the required permission for the operation you attempted (read, write, or execute).
Why This Happens
Every file on Linux and macOS has owner, group, and permission attributes. On Windows, files have ACLs (Access Control Lists). When Python opens a file, the OS checks whether the current user has permission for the requested operation.
The most common causes:
- Writing to a system directory (
/usr/,/var/,/etc/) without root/admin privileges. - File owned by a different user. The file was created by
rootor another user, and your account cannot access it. - File is read-only. The write permission bit is not set.
- Directory does not allow listing or writing. You need execute permission on a directory to access files inside it.
- Windows file lock. Another process has the file open exclusively.
- Antivirus or security software is blocking access.
- SELinux or AppArmor policies are restricting file access beyond standard Unix permissions.
- Trying to write to a read-only filesystem (like a Docker container’s root filesystem or a mounted CD/USB).
Fix 1: Check and Fix File Permissions
First, check the current permissions:
ls -la /path/to/fileOutput:
-rw-r--r-- 1 root root 1234 Mar 9 10:00 myfile.txtThis means: owner (root) can read/write, group and others can only read. If your user is not root, you cannot write to this file.
Change permissions:
chmod 664 /path/to/file # Owner and group can read/write, others can read
chmod 666 /path/to/file # Everyone can read/writeChange ownership to your user:
sudo chown $USER:$USER /path/to/fileFor directories, apply recursively:
sudo chown -R $USER:$USER /path/to/directoryThis is the same approach used for fixing bash permission denied errors — the underlying cause is identical.
Common Mistake: Using
chmod 777to fix permission issues. This gives everyone full read, write, and execute access, which is a security risk. Use the minimum permissions needed:644for files (owner writes, others read) and755for directories.
Fix 2: Don’t Write to System Directories
If your script tries to write to /usr/, /var/log/, /etc/, or other system directories, that is the problem. Normal users should not write to these locations.
Fix: Write to user-accessible locations:
import os
from pathlib import Path
# Write to the user's home directory
home = Path.home()
log_file = home / "myapp" / "app.log"
log_file.parent.mkdir(parents=True, exist_ok=True)
with open(log_file, "w") as f:
f.write("log entry\n")Or use a temporary directory:
import tempfile
with tempfile.NamedTemporaryFile(mode="w", suffix=".log", delete=False) as f:
f.write("temporary log")
print(f.name) # /tmp/tmpXXXXXX.logFor application data, use platform-appropriate directories:
import os
# Linux: ~/.local/share/myapp
# macOS: ~/Library/Application Support/myapp
# Windows: C:\Users\<user>\AppData\Local\myapp
data_dir = os.path.join(os.path.expanduser("~"), ".local", "share", "myapp")
os.makedirs(data_dir, exist_ok=True)Fix 3: Use Virtual Environments Instead of sudo pip
If the error happens during pip install:
PermissionError: [Errno 13] Permission denied: '/usr/local/lib/python3.12/site-packages/...'Do not use sudo pip install. This installs packages system-wide, which can conflict with system Python and break OS tools.
Fix: Use a virtual environment:
python -m venv venv
source venv/bin/activate # Linux/macOS
# or: venv\Scripts\activate # Windows
pip install some-package # Installs to venv, no sudo neededIf you see externally-managed-environment errors on newer systems, see fixing pip externally managed environment.
Pro Tip: Always use virtual environments for Python projects. They isolate dependencies, prevent permission issues, and avoid conflicts between projects. Tools like
poetry,pipenv, anduvcreate virtual environments automatically.
Fix 4: Fix Directory Permissions
If the error points to a directory rather than a file, you need execute permission on the directory to access its contents:
ls -la /path/to/Directories need the execute bit (x) for traversal:
chmod 755 /path/to/directory # Owner: rwx, Group/Others: rxA common scenario: your script creates a subdirectory but the parent directory doesn’t allow writing:
os.makedirs("/opt/myapp/data", exist_ok=True)
# PermissionError if /opt/ doesn't allow writingFix: Create the directory in a writable location, or use sudo to create it once and change ownership:
sudo mkdir -p /opt/myapp/data
sudo chown -R $USER:$USER /opt/myappFor similar Node.js permission issues, see fixing EACCES permission denied mkdir.
Fix 5: Handle Windows File Locks
On Windows, a file can be locked exclusively by another process. If Excel, a text editor, or another Python script has the file open, your script cannot write to it:
PermissionError: [Errno 13] Permission denied: 'report.xlsx'Fix: Close the other program that has the file open. Or check which process holds the lock:
# Find processes using the file
Get-Process | Where-Object { $_.Modules.FileName -like "*report.xlsx*" }Or use tools like Process Explorer or Handle from Sysinternals.
In your code, handle the error gracefully:
import time
def write_with_retry(filepath, content, retries=3):
for attempt in range(retries):
try:
with open(filepath, "w") as f:
f.write(content)
return
except PermissionError:
if attempt < retries - 1:
time.sleep(1)
else:
raiseFix 6: Handle Antivirus and Security Software
Antivirus programs (Windows Defender, Norton, McAfee, etc.) can block Python from writing to certain locations. This is especially common with:
- Files in the Downloads folder
- Executable files (
.exe,.bat,.ps1) - Files matching patterns that look like malware
Fix: Add your project directory to the antivirus exclusion list. For Windows Defender:
- Open Windows Security → Virus & threat protection
- Click “Manage settings” under “Virus & threat protection settings”
- Scroll to “Exclusions” → “Add or remove exclusions”
- Add your project folder
Fix 7: Check SELinux and AppArmor (Linux)
On RHEL, CentOS, Fedora, and Amazon Linux, SELinux can block file access even when Unix permissions allow it. The error looks identical to a regular permission denied.
Check if SELinux is enforcing:
getenforceIf it returns Enforcing, check the SELinux audit log:
sudo ausearch -m avc -ts recentFix the SELinux context for your files:
sudo restorecon -Rv /path/to/filesOr set a permissive context for your application directory:
sudo chcon -R -t httpd_sys_rw_content_t /path/to/writable/dirOn Ubuntu, AppArmor can cause similar issues. Check its status:
sudo aa-statusFix 8: Use os.access() to Check Before Opening
Instead of crashing on PermissionError, check permissions first:
import os
filepath = "/path/to/file"
if os.access(filepath, os.W_OK):
with open(filepath, "w") as f:
f.write("data")
else:
print(f"No write permission for {filepath}")Available checks:
| Flag | Checks |
|---|---|
os.R_OK | Read permission |
os.W_OK | Write permission |
os.X_OK | Execute permission |
os.F_OK | File exists |
Note: There is a TOCTOU (time-of-check-time-of-use) race condition with this approach. The permission could change between the check and the open. For critical applications, use try/except instead:
try:
with open(filepath, "w") as f:
f.write("data")
except PermissionError:
print(f"Cannot write to {filepath}")Fix 9: Handle Docker Container Permissions
Inside Docker containers, permission errors are common when:
- The container runs as root but the mounted volume was created by a different user
- The container runs as a non-root user but needs to write to directories created during build
Fix volume permission issues:
docker run -v /host/path:/container/path -u $(id -u):$(id -g) myappThe -u flag runs the container as your host user, matching file ownership.
Or fix permissions in the Dockerfile:
RUN mkdir -p /app/data && chown -R 1000:1000 /app/data
USER 1000For more Docker volume permission issues, see Fix: Docker volume permission denied.
Still Not Working?
If none of the fixes above resolved the error:
Check for read-only filesystems. Some Docker containers, Kubernetes pods, or cloud environments mount the root filesystem as read-only. Write to /tmp or a mounted volume instead.
Check for NFS or network mount issues. Network-mounted filesystems may have different permission rules. root_squash on NFS servers prevents root from writing. Contact your sysadmin for NFS permission issues.
Check Python’s own file. If the error is during python script.py, check that the script file itself is readable:
chmod 644 script.pyIf Python itself isn’t found, see Fix: python command not found.
Check for immutable flags. On Linux, files can be marked immutable with chattr:
lsattr /path/to/fileIf you see i in the flags, the file cannot be modified even by root:
sudo chattr -i /path/to/fileUse strace to debug (Linux):
strace -e openat python script.py 2>&1 | grep EACCESThis shows exactly which file system call is failing and why.
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.