There is very little difference between the two types. In fact, even the core Python developers agreed that there is no real difference and removed IOError in Python 3 (it is now an alias for OSError). See PEP 3151 - Reworking the OS and IO exception hierarchy:

While some of these distinctions can be explained by implementation considerations, they are often not very logical at a higher level. The line separating OSError and IOError, for example, is often blurry. Consider the following:

>>> os.remove("fff")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: 'fff'
>>> open("fff")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'fff'

Yes, that's two different exception types with the exact same error message.

For your own code, stick to throwing OSError. For existing functions, check the documentation (it should detail what you need to catch), but you can safely catch both:

try:
    # ...
except (IOError, OSError):
    # handle error

Quoting the PEP again:

In fact, it is hard to think of any situation where OSError should be caught but not IOError, or the reverse.

Answer from Martijn Pieters on Stack Overflow
🌐
Python
docs.python.org › 3 › builtins › exceptions.html
Built-in Exceptions — Python 3.14.7 documentation
The tuple of arguments given to the exception constructor. Some built-in exceptions (like OSError) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single ...
🌐
Real Python
realpython.com › ref › builtin-exceptions › oserror
OSError | Python’s Built-in Exceptions – Real Python
OSError is a built-in exception that acts as the base class for system-related errors in Python, including file handling, hardware issues, or other low-level OS tasks.
Discussions

Catch a Specific OSError Exception in Python 3 - Stack Overflow
In Python 3, how can we catch a specific OSError exception? My current code catches all OSError, but only OSError: [Errno 12] needs to be caught. try: foo() except OSError as e: print('Caught More on stackoverflow.com
🌐 stackoverflow.com
py3.3+: IOError (and others) -> OSError
In Python 3.3+ the following exceptions are now simple aliases of OSError: IOError, EnvironmentError, WindowsError, mmap.error, socket.error and select.error. The aliases have been removed from the... More on github.com
🌐 github.com
5
May 10, 2019
"except OSError" is also catching FileNotFound Error
FileNotFoundError is a subclass of OSError. Since it's type is OSError, it gets excepted in the first except OSError: block and it never gets to except FileNotFound:. Switch the order and it should work fine: try: subprocess.Popen(file) except FileNotFoundError: print('File missing') except OSError: print('OSError') https://docs.python.org/3/library/exceptions.html#os-exceptions The following exceptions are subclasses of OSError, they get raised depending on the system error code. ... exception FileNotFoundError Raised when a file or directory is requested but doesn’t exist. Corresponds to errno ENOENT. More on reddit.com
🌐 r/learnpython
7
2
December 19, 2018
exception - Python - except (OSError, e) - No longer working in 3.3.3? - Stack Overflow
The following have worked throughout Python 3.X and is not broke in 3.3.3, can't find what's changed in the docs. import os def pid_alive(pid): pid = int(pid) if pid More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org › python › handling-oserror-exception-in-python
Handling OSError exception in Python - GeeksforGeeks
July 1, 2026 - OSError occurs when a program encounters an operating system-related problem while performing tasks such as working with files, directories, devices, or system resources. Common causes include accessing a missing file, insufficient permissions, ...
🌐
W3Schools
w3schools.com › python › python_ref_exceptions.asp
Python Built-in Exceptions
The table below shows built-in exceptions that are usually raised in Python.
Find elsewhere
🌐
Python documentation
docs.python.org › 3 › tutorial › errors.html
8. Errors and Exceptions — Python 3.14.7 documentation
except* SystemError as e: ... print("There were SystemErrors") ... There were OSErrors There were SystemErrors + Exception Group Traceback (most recent call last): | File "<stdin>", line 2, in <module> | f() | ~^^ | File "<stdin>", line 2, in f | raise ExceptionGroup( | ...<12 lines>... | ) | ExceptionGroup: group1 (1 sub-exception) +-+---------------- 1 ---------------- | ExceptionGroup: group2 (1 sub-exception) +-+---------------- 1 ---------------- | RecursionError: 4 +------------------------------------ >>>
🌐
Read the Docs
python.readthedocs.io › fr › latest › library › exceptions.html
5. Built-in Exceptions — documentation Python 3.7.0a0
The tuple of arguments given to the exception constructor. Some built-in exceptions (like OSError) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single string giving an error message.
🌐
GitHub
github.com › asottile › pyupgrade › issues › 141
py3.3+: IOError (and others) -> OSError · Issue #141 · asottile/pyupgrade
May 10, 2019 - In Python 3.3+ the following exceptions are now simple aliases of OSError: IOError, EnvironmentError, WindowsError, mmap.error, socket.error and select.error. The aliases have been removed from the documented hierarchy: https://docs.pyth...
Author: asottile
🌐
Reddit
reddit.com › r/learnpython › "except oserror" is also catching filenotfound error
r/learnpython on Reddit: "except OSError" is also catching FileNotFound Error
December 19, 2018 -

I'm working on a small project to group scripts and allow me to execute them from a single interface, but I'm running into an issue with my error handling. My code looks like this:

try:
    subprocess.Popen(file)
except OSError:
    print('execution failed.')

However, the except block keeps catching the FileNotFound error as well. If I change the code to this:

try:
    subprocess.Popen(file)
except OSError:
    print('OSError')
except FileNotFoundError:
    print('File missing')

and then trigger a FileNotFoundError, I receive the 'OSError' message.

I am using Python 3.7.1.

Any idea what I'm doing wrong?

EDIT: More testing. If I reverse the order like so:

try:
    subprocess.Popen(file)
except FileNotFoundError:
    print('File missing')
except OSError:
    print('OSError')

then the first exception block catches the FileNotFoundError before it makes it to the second block. And an OSError is passed by the first block and caught by the second block. So it seems to work this way. However I am still concerned about OSError catching exceptions it shouldn't. If new error occurs that I have not prepared for, I don't want it to be reported as an OSError.

🌐
Real Python
realpython.com › ref › builtin-exceptions › ioerror
IOError | Python’s Built-in Exceptions – Real Python
In Python, IOError is a built-in exception that was used to handle input/output (I/O) related errors, such as problems reading or writing files.
🌐
Sololearn
sololearn.com › en › Discuss › 1478477 › what-is-oserror-in-python
What is OSerror in python? | Sololearn: Learn to code for FREE!
exception OSError¶ This exception is derived from EnvironmentError. It is raised when a function returns a system-related error (not for illegal argument types or other incidental errors).
🌐
Medium
medium.com › @rayancrazer › os-error-and-overflow-error-in-python-9c4e7b917dd7
Python Errors Uncovered: Handling OS and Overflow Issues Effectively
November 24, 2024 - In conclusion, when developing applications in Python, it’s essential to handle OS errors gracefully. The os module provides many functions that can throw OS errors, and you can use the try-except block to handle these errors.
🌐
Reddit
reddit.com › r/learnpython › what’s the difference between ioerror and oserror in python?
What’s the difference between IOError and OSError in python? : r/learnpython
November 11, 2020 - It also says IOError was merged with OSError. There is also a FileNotFoundError for when a file doesn't exist. Note that these are conventions, libraries can raise whatever they want. Your best bet is to read the documentation of the functions you're calling. ... I finished Helsinki's Advanced Programming course and would like to know what some popular courses are that could come after this one. Perhaps about DSA or other. ... Python is so confusing to me.
🌐
Help & Support
support.microbit.org › support › solutions › articles › 19000126750-python-oserror-codes
Python OSError Codes : Help & Support
May 20, 2021 - A list of Python OSError codes and descriptions raised when a system operation causes a system-related error, including I/O failures such as “file not found” or “disk full” If you see these errors in your python program and are unsure what to...
🌐
Embedded Inventor
embeddedinventor.com › home › hierarchy of exceptions in python
Hierarchy of Exceptions in Python
December 27, 2023 - OSError: The base class for all the operating system related exceptions.
🌐
Python
bugs.python.org › issue35743
Issue 35743: Broken "Exception ignored in:" message on OSError's - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/79924