ModuleNotFoundError

"No module named x" is about the interpreter that ran the code: the package is missing from that Python's environment, or its folder is not on that Python's sys.path — installing it "somewhere" is not enough.

InheritsBaseException›Exception›ImportError›ModuleNotFoundError
Import / syntax exceptionPython 3.6+
ModuleNotFoundError(*args, namename — Keyword-only. The module that could not be found.type: str | None · default: None=None, pathpath — Keyword-only. Inherited from ImportError; normally None here.type: str | None · default: None=None)
Raised by
import x, from x import y, importlib.import_module(), __import__()
Message
No module named 'x' · No module named 'a.b'; 'a' is not a package
Quick fix
python -m pip install <package> — with the same python that runs the code
Watch out
the pip name is not always the import name (pip install pyyaml → import yaml)

Constructor

NameTypeRequiredDescription
*argsobjectnoUsually one message string, "No module named 'x'".
namestr | Noneno (None)Keyword-only. The module that could not be found.
pathstr | Noneno (None)Keyword-only. Inherited from ImportError; normally None here.

Attributes

AttributeTypeMeaning
namestr | NoneThe first module in the dotted path that is missing: for import pkg.sub with no pkg it is 'pkg'; with pkg present but no sub it is 'pkg.sub'.
msgstrThe message, "No module named 'x'" (plus "; 'a' is not a package" when a parent is a plain module).
pathstr | NoneInherited from ImportError; None for a module that was not found.

Common patterns

Install into the interpreter you run
Run pip through the same python. In a notebook, %pip install installs into the kernel's environment.
import sys, subprocess
# which python is this? install into exactly that one
print(sys.executable)
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'requests'])
Optional dependency with a clear message
Catch ModuleNotFoundError (not every ImportError) and say what to install.
try:
    import yaml
except ModuleNotFoundError as e:
    raise SystemExit(f'{e.name} is missing: pip install pyyaml') from None
Check without importing
find_spec returns None instead of raising for a missing top-level module.
import importlib.util
HAS_NUMPY = importlib.util.find_spec('numpy') is not None

Examples

1. Module that is not installed
import requests_not_installed_xyz
Returns
ModuleNotFoundError: No module named 'requests_not_installed_xyz'
2. e.name is the first missing piece
try: import nosuch_pkg_mnf.sub except ModuleNotFoundError as e: r = (e.name, e.msg) r
Returns
('nosuch_pkg_mnf', "No module named 'nosuch_pkg_mnf'")
3. Parent is a module, not a package
import os.path.nope
Returns
ModuleNotFoundError: No module named 'os.path.nope'; 'os.path' is not a package
4. Removed from the standard library
import imp
Returns
ModuleNotFoundError: No module named 'imp'
5. None in sys.modules blocks an import
import sys sys.modules['mnf_blocked'] = None try: import mnf_blocked except ModuleNotFoundError as e: r = str(e) finally: del sys.modules['mnf_blocked'] r
Returns
'import of mnf_blocked halted; None in sys.modules'
6. find_spec() checks without raising
import importlib.util importlib.util.find_spec('mnf_missing_xyz') is None
Returns
True
7. It is an ImportError
e = ModuleNotFoundError("No module named 'yaml'", name='yaml') (str(e), e.name, isinstance(e, ImportError))
Returns
("No module named 'yaml'", 'yaml', True)

Pitfalls

1. Not checking which module is missing
A package that IS installed can raise ModuleNotFoundError for one of its own dependencies. A bare except then takes the "not installed" path and hides the real problem. Compare e.name with the module you tried to import and re-raise anything else.
Any missing module
import os, sys
with open('mnf_wrap_a.py', 'w') as f:
    f.write('import mnf_dep_a\n')
sys.path.insert(0, os.getcwd())
try:
    import mnf_wrap_a
except ModuleNotFoundError:
    mnf_wrap_a = None
finally:
    sys.path.remove(os.getcwd())
mnf_wrap_a is None
True
Check e.name
import os, sys
with open('mnf_wrap_b.py', 'w') as f:
    f.write('import mnf_dep_b\n')
sys.path.insert(0, os.getcwd())
try:
    import mnf_wrap_b
except ModuleNotFoundError as e:
    if e.name != 'mnf_wrap_b':
        raise
    mnf_wrap_b = None
finally:
    sys.path.remove(os.getcwd())
ModuleNotFoundError: No module named 'mnf_dep_b'
2. Using the pip name as the import name
Distribution names on PyPI and module names often differ: pyyaml → yaml, beautifulsoup4 → bs4, scikit-learn → sklearn, opencv-python → cv2, pillow → PIL. Importing the distribution name fails even after a successful install.
import pyyaml
import pyyaml_mnf_example
ModuleNotFoundError: No module named 'pyyaml_mnf_example'
Check the docs for the import name
import importlib.util
importlib.util.find_spec('json') is not None
True

When to use

Use it
  • Optional dependencies: catch it, check e.name, fall back or explain what to install
  • Plugin systems that import modules by name from configuration
Reach for something else
  • Catching it to hide a missing required dependency → fail loudly with the install command
  • Checking the Python version for stdlib modules → catch it, or check sys.version_info

Notes

CPython impl
Lib/importlib/_bootstrap.py _find_and_load_unlocked() — "No module named …"; "; 'x' is not a package" when the parent has no __path__
Catch via
except ImportError catches it too (it is a subclass)
Shadowing (3.13)
A local file named like the module is imported first; 3.13 appends "(consider renaming …)" to the resulting AttributeError/ImportError
sys.path[0]
The script's own directory (or the current directory for -m, -c and the REPL) is searched first

FAQ

Whether an import succeeds depends entirely on the environment of the interpreter that runs it — which packages are installed, which virtual environment is active, the operating system, and sys.path. A browser demo cannot reproduce your environment honestly, so the examples use module names that cannot exist anywhere, plus stdlib behavior that is the same on every platform.

History

3.6
Added as a subclass of ImportError.