# How to Fix Python OSError: [Errno]
The OSError is a broad exception class that wraps system-level errors returned by the operating system. These errors include file operations, network issues, and other OS-level failures, identified by specific errno codes.
Error Patterns
File Not Found (errno 2)
Traceback (most recent call last):
File "app.py", line 3, in <module>
os.remove("missing.txt")
OSError: [Errno 2] No such file or directory: 'missing.txt'Permission Denied (errno 13)
Traceback (most recent call last):
File "app.py", line 5, in <module>
open("/etc/shadow", "w")
PermissionError: [Errno 13] Permission denied: '/etc/shadow'Directory Not Empty (errno 39)
Traceback (most recent call last):
File "app.py", line 7, in <module>
os.rmdir("nonempty_dir")
OSError: [Errno 39] Directory not empty: 'nonempty_dir'Too Many Open Files (errno 24)
Traceback (most recent call last):
File "app.py", line 10, in <module>
open(f"file_{i}.txt") # Loop creating many files
OSError: [Errno 24] Too many open filesNetwork Errors
Traceback (most recent call last):
File "app.py", line 15, in <module>
socket.connect((host, port))
OSError: [Errno 111] Connection refusedCommon Errno Codes
| Errno | Name | Description |
|---|---|---|
| 2 | ENOENT | No such file or directory |
| 13 | EACCES | Permission denied |
| 17 | EEXIST | File exists |
| 22 | EINVAL | Invalid argument |
| 24 | EMFILE | Too many open files |
| 28 | ENOSPC | No space left on device |
| 30 | EROFS | Read-only file system |
| 39 | ENOTEMPTY | Directory not empty |
| 54 | ECONNRESET | Connection reset by peer |
| 111 | ECONNREFUSED | Connection refused |
| 113 | EHOSTUNREACH | No route to host |
Common Causes
- 1.Missing files/directories - Path doesn't exist
- 2.Permission issues - Insufficient access rights
- 3.Disk full - No storage space available
- 4.Too many open files - Exceeded system limits
- 5.Invalid file names - Illegal characters or length
- 6.Read-only filesystem - Cannot write to location
- 7.Network failures - Connection issues
- 8.Resource limits exceeded - System limits reached
Diagnosis Steps
Step 1: Check Errno and Message
```python import os import errno
try: os.remove("missing.txt") except OSError as e: print(f"Errno: {e.errno}") print(f"Message: {e.strerror}") print(f"Filename: {e.filename}")
# Compare with known errno values if e.errno == errno.ENOENT: print("File not found") elif e.errno == errno.EACCES: print("Permission denied") ```
Step 2: Check System State
```bash # Linux/Mac diagnostics df -h # Disk space ls -la filename # File permissions lsof -p $$ # Open files for current process ulimit -n # File descriptor limit cat /proc/sys/fs/file-max # System max files
# Windows dir filename # File info wmic logicaldisk # Disk space ```
Step 3: Check File/Directory State
```python import os from pathlib import Path
path = Path("target_file")
# Check existence print(f"Exists: {path.exists()}")
# Check permissions print(f"Readable: {os.access(path, os.R_OK) if path.exists() else 'N/A'}") print(f"Writable: {os.access(path, os.W_OK) if path.exists() else 'N/A'}") print(f"Executable: {os.access(path, os.X_OK) if path.exists() else 'N/A'}")
# Check parent directory parent = path.parent print(f"Parent exists: {parent.exists()}") print(f"Parent writable: {os.access(parent, os.W_OK) if parent.exists() else 'N/A'}") ```
Solutions
Solution 1: Handle FileNotFoundError (errno 2)
```python import os from pathlib import Path
# Problem: File doesn't exist os.remove("missing.txt") # OSError errno 2
# Fix: Check before operation path = Path("missing.txt") if path.exists(): path.unlink() else: print("File not found, skipping removal")
# Or use try/except try: os.remove("missing.txt") except FileNotFoundError: # Subclass of OSError print("File not found") except OSError as e: print(f"Other error: {e}") ```
Solution 2: Handle PermissionError (errno 13)
```python import os
# Problem: No permission with open("/etc/shadow", "w"): # OSError errno 13
# Fix: Check permissions first path = "/etc/shadow" if os.access(path, os.W_OK): with open(path, "w") as f: f.write("data") else: print("No write permission") # Ask for elevated permissions or use different path
# Fix: Use user-accessible path user_path = os.path.expanduser("~/output.txt") with open(user_path, "w") as f: f.write("data") ```
Solution 3: Handle Directory Not Empty (errno 39)
```python import os import shutil
# Problem: Cannot remove non-empty directory os.rmdir("nonempty_dir") # OSError errno 39
# Fix: Use shutil.rmtree for non-empty directories shutil.rmtree("nonempty_dir") # Removes directory and contents
# Or check and handle path = "nonempty_dir" if os.path.isdir(path): if os.listdir(path): # Directory has contents shutil.rmtree(path) else: os.rmdir(path) ```
Solution 4: Handle Too Many Open Files (errno 24)
```python import os
# Problem: Opening too many files without closing files = [] for i in range(10000): files.append(open(f"file_{i}.txt")) # OSError errno 24
# Fix: Close files after use for i in range(10000): with open(f"file_{i}.txt") as f: # Auto-closes content = f.read()
# Fix: Increase file descriptor limit import resource soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard)) # Increase limit
# Fix: Use file pooling from contextlib import ExitStack with ExitStack() as stack: files = [stack.enter_context(open(f"file_{i}.txt")) for i in range(100)] # All files closed when ExitStack exits ```
Solution 5: Handle Disk Full (errno 28)
```python import os
# Problem: No space left on device with open("large_file", "w") as f: f.write(large_data) # OSError errno 28
# Fix: Check disk space before writing import shutil
def get_free_space(path): """Get free space in bytes.""" total, used, free = shutil.disk_usage(path) return free
def safe_write(path, data): """Write with disk space check.""" free = get_free_space(os.path.dirname(path)) required = len(data) + 1024 # Add buffer
if free < required: raise OSError(f"Insufficient disk space: {free} bytes free, {required} needed")
with open(path, "w") as f: f.write(data) ```
Solution 6: Handle Read-Only Filesystem (errno 30)
```python import os
# Problem: Cannot write to read-only filesystem with open("/mnt/cdrom/file.txt", "w") as f: # OSError errno 30
# Fix: Check filesystem mount options import subprocess
def is_readonly(path): """Check if filesystem is read-only.""" # Linux: check mount options mount_output = subprocess.run(['mount'], capture_output=True, text=True) for line in mount_output.stdout.split('\n'): if path in line and 'ro' in line: return True return False
# Use writable location if is_readonly("/mnt/cdrom"): write_path = "/tmp/output.txt" else: write_path = "/mnt/cdrom/file.txt" ```
Solution 7: Handle Network OSError
```python import socket
# Problem: Network errors sock = socket.socket() sock.connect(("unreachable.host", 80)) # OSError errno 113
# Fix: Handle network errors with retry import time
def connect_with_retry(host, port, retries=3, delay=1): sock = socket.socket() for attempt in range(retries): try: sock.connect((host, port)) return sock except OSError as e: if e.errno in (socket.ECONNREFUSED, socket.EHOSTUNREACH): if attempt < retries - 1: time.sleep(delay) continue raise return None
# Fix: Use timeout sock = socket.socket() sock.settimeout(5) # 5 second timeout try: sock.connect((host, port)) except socket.timeout: print("Connection timed out") ```
Solution 8: Handle Invalid Argument (errno 22)
```python import os
# Problem: Invalid filename (null byte, too long, etc.) open("file\x00name.txt") # OSError errno 22 (null byte in name) open("x" * 5000) # OSError errno 22 (name too long)
# Fix: Validate filename before use import re
def is_valid_filename(filename): """Check if filename is valid.""" # No null bytes if '\x00' in filename: return False # Not too long (most systems: 255 chars) if len(filename) > 255: return False # No invalid characters (depends on OS) if re.search(r'[<>:"|?*]', filename) and os.name == 'nt': # Windows return False return True
# Sanitize filename def sanitize_filename(filename): """Create safe filename.""" # Remove null bytes filename = filename.replace('\x00', '') # Truncate to valid length filename = filename[:255] # Remove Windows-invalid chars if os.name == 'nt': filename = re.sub(r'[<>:"|?*]', '_', filename) return filename ```
OSError Subclasses
Python provides specific subclasses for common OSError types:
```python # FileNotFoundError - errno 2 try: open("missing.txt") except FileNotFoundError: print("File not found")
# PermissionError - errno 13 try: open("/root/secret") except PermissionError: print("Permission denied")
# FileExistsError - errno 17 try: os.mkdir("existing_dir") except FileExistsError: print("Directory exists")
# IsADirectoryError - errno 21 try: open("directory_path") except IsADirectoryError: print("Path is a directory")
# NotADirectoryError - errno 20 try: os.listdir("file.txt") except NotADirectoryError: print("Path is not a directory")
# ConnectionError (network) try: socket.connect() except ConnectionError: print("Connection failed") ```
Cross-Platform Handling
```python import os import errno
def handle_os_error(e): """Handle OSError with platform awareness.""" error_map = { errno.ENOENT: "File/directory not found", errno.EACCES: "Permission denied", errno.EEXIST: "File already exists", errno.ENOSPC: "Disk full", errno.EROFS: "Read-only filesystem", errno.ENOTEMPTY: "Directory not empty", errno.EMFILE: "Too many open files", }
# Platform-specific codes if os.name == 'nt': # Windows win_errors = { 5: "Access denied", 32: "File in use", 183: "File already exists", } if hasattr(e, 'winerror') and e.winerror in win_errors: return win_errors[e.winerror]
return error_map.get(e.errno, str(e))
try: os.remove("some_file") except OSError as e: print(handle_os_error(e)) ```
Prevention Tips
- 1.Check existence before file operations
- 2.Check permissions before read/write
- 3.Use with statements for automatic cleanup
- 4.Validate paths before operations
- 5.Handle errors gracefully with specific exception types
```python import os from pathlib import Path
# Good pattern: Comprehensive file operation def safe_file_operation(path, operation): path = Path(path)
# Validate path if not is_valid_filename(path.name): raise ValueError(f"Invalid filename: {path.name}")
# Check parent exists if not path.parent.exists(): raise FileNotFoundError(f"Parent directory not found: {path.parent}")
# Check permissions if operation in ('w', 'a', 'x'): if not os.access(path.parent, os.W_OK): raise PermissionError(f"Cannot write to: {path.parent}")
# Perform operation with error handling try: return operation(path) except OSError as e: # Handle with context raise OSError(f"Failed {operation} on {path}: {e.strerror}") ```
Related Errors
FileNotFoundError- Specific for missing filesPermissionError- Specific for access deniedConnectionError- Network-related OSErrorIOError- Alias for OSError in Python 3