OSError, what it means and how to fix it

OSError is how the operating system's refusals reach Python: the file system, the network stack, and process machinery report failures as an error number (errno) plus a message, and Python raises them as OSError or one of its more specific subclasses. Reading an OSError means reading its payload: the errno, the system's own description, and the filename or address it names are the diagnosis; the class name alone is just the envelope.

What it looks like

open("/mnt/data/results.txt", "w")

Traceback (most recent call last):
  File "main.py", line 1, in <module>
OSError: [Errno 28] No space left on device:
'/mnt/data/results.txt'

# the errno is the error: 28 = the disk (or quota) is full,
# which no amount of path-checking would have found

The fix, in order

  1. Read the errno first; it is the actual error. Common values: 2 no such file, 13 permission denied, 22 invalid argument, 24 too many open files, 28 no space left on device, 30 read-only file system, 36 file name too long, 110 connection timed out. Each has its own remedy, and the generic class hides all of them.
  2. Check whether a subclass names your case better. FileNotFoundError, PermissionError, IsADirectoryError, FileExistsError, TimeoutError, and the ConnectionError family are all OSErrors with their own pages and fixes. Code (and debugging) should use the narrowest class that appears.
  3. For space and quota errors (28), confirm with the OS (df -h, and df -i for inodes, the forgotten twin: a filesystem can be out of inodes with bytes to spare) and clear the actual constraint rather than retrying the write.
  4. For too many open files (24), files or sockets are being opened without closing. The durable fix is with blocks (or explicit close in finally) so handles are released deterministically; raising the process limit (ulimit -n) buys time but does not stop a leak.
  5. For invalid argument (22), the usual culprits are illegal characters or trailing spaces and dots in Windows filenames, NUL bytes in paths, and timestamps or flags outside the platform's range. Print the exact repr of the argument being passed.

If it still happens

An OSError with errno 5 (input/output error) on storage, or intermittent 11 (resource temporarily unavailable) under load, points below the software: failing disks, flaky network mounts, and exhausted system resources. Correlate with system logs; the Python traceback is the smoke, not the fire.

Common questions

Why catch OSError instead of the specific subclass? Catching OSError catches every OS failure including ones you did not foresee, which suits broad boundaries (a top-level “couldn't complete the operation” handler). For specific remedies, catch the subclass, or inspect the exception's .errno attribute and branch on it.

Where does the list of errno meanings live? In the errno module: errno.errorcode maps numbers to names like ENOSPC, and os.strerror(n) gives the description text. Printing e.errno and os.strerror(e.errno) in a handler produces the same words the traceback shows.

Related errors

FileNotFoundError · PermissionError · BrokenPipeError