Skip to content

Fix: ModuleNotFoundError: No module named in Python

FixDevs · (Updated: )

Part of:  Python Errors

Quick Answer

How to fix 'ModuleNotFoundError: No module named' and 'ImportError: No module named' in Python. Covers pip install, pip vs pip3, virtual environments, package name vs import name mismatches, PYTHONPATH, and IDE interpreter issues.

The Error

You try to run a Python script and get this:

Python 3:

Traceback (most recent call last):
  File "app.py", line 1, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'

Python 2 (or early Python 3):

Traceback (most recent call last):
  File "app.py", line 1, in <module>
    import requests
ImportError: No module named requests

Both mean the same thing: Python can’t find the module you’re trying to import. ModuleNotFoundError was introduced in Python 3.6 as a subclass of ImportError, so older Python versions raise ImportError instead.

Why This Happens

Python looks for modules in a specific list of directories (stored in sys.path). When the module isn’t in any of them, you get this error.

The interpreter builds sys.path from several sources at startup: the directory of the running script, the value of PYTHONPATH, the standard library directory, and the site-packages directories of the active environment. Anything outside this list is invisible to import. The result is that “the package is installed” and “the package is on Python’s search path” are two different statements, and the gap between them is where this error lives.

Most of the time, the package exists somewhere on your machine but not in the site-packages of the Python that is actually running your script. Multiple Python installations, a forgotten venv, an IDE pointing at the wrong interpreter, or a recent change in OS-level Python policy can all cause this gap.

The most common causes:

  • The package isn’t installed. You’re importing a third-party package that was never installed with pip.
  • You installed the package with a different Python or pip. Your system has multiple Python versions, and you ran pip install for one but are running the script with another.
  • Your virtual environment isn’t activated. The package is installed in a venv, but you’re running Python outside of it (or vice versa).
  • The package name doesn’t match the import name. You install Pillow but import PIL. You install opencv-python but import cv2. This mismatch is a frequent source of confusion.
  • The Python version doesn’t support the package. The package requires a newer (or older) Python than what you have.
  • A system Python now refuses installs via PEP 668. Recent distro Pythons (Debian 12, Ubuntu 23.04+, Homebrew Python 3.11+) raise externally-managed-environment when you run pip install, leaving you with no installed package.

A Note on Python Packaging History

The packaging ecosystem has changed in ways that directly affect this error. Older tutorials still walk you through patterns that no longer work on modern systems.

virtualenv vs venv. virtualenv is the original third-party tool, dating back to 2007. The standard library shipped its own subset as venv in Python 3.3 (2012). For new projects, prefer python -m venv .venv — it is built in, fast enough, and the directory layout matches what tools like VS Code, PyCharm, and uv expect. virtualenv still exists and is the right choice if you need to create environments for older Python interpreters or want extra features like seed packages, but most everyday work should use the built-in module.

site-packages locations have moved. On modern Linux distributions, the system Python’s site-packages lives in /usr/lib/python3.X/dist-packages (Debian/Ubuntu) or /usr/lib/python3.X/site-packages (Fedora/Arch). On macOS, Homebrew puts user-installed Python under /opt/homebrew/lib/python3.X/site-packages (Apple Silicon) or /usr/local/lib/python3.X/site-packages (Intel). User-level installs land in ~/.local/lib/python3.X/site-packages on Linux/macOS and %APPDATA%\Python\Python3X\site-packages on Windows. Knowing where each layer lives makes it much easier to interpret the output of pip show and python -c "import sys; print(sys.path)".

PEP 668 changed how system Pythons behave. Starting with Debian 12 (June 2023), Ubuntu 23.04, Homebrew Python 3.11+, and most Linux distros that followed, the system Python ships with an EXTERNALLY-MANAGED marker file. Running pip install directly on that interpreter now raises:

error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to install.

The fix is to stop installing into the system Python at all. Create a venv (python -m venv .venv && source .venv/bin/activate) and install there, or use pipx for command-line tools. The escape hatches --break-system-packages and pip config set global.break-system-packages true exist but are explicitly named to warn you that they break the distro’s package manager invariants. If you only see PEP 668 errors and not ModuleNotFoundError, see Fix: pip externally-managed-environment.

pip install --user is the historical workaround, but it interacts badly with venv (the user site is suppressed inside a venv) and badly with PEP 668 (the system installer still owns the user namespace on some distros). It is no longer the first thing to try.

Fix 1: Install the Package

If you haven’t installed the package yet, install it with pip:

pip install requests

If you’re not sure whether it’s installed, check:

pip show requests

This prints the package’s version and install location. If it says WARNING: Package(s) not found, the package isn’t installed.

You can also list all installed packages:

pip list

Common Mistake: Running pip install in one terminal and python in another can silently use different Python versions. Always verify with pip --version and python --version that they point to the same Python installation before assuming the package is missing.

Fix 2: Use the Correct pip (pip vs pip3)

This is the most common cause of “I installed it but Python still can’t find it.” You installed the package with one Python version but are running the script with another.

On many systems, pip is linked to Python 2 and pip3 is linked to Python 3. Or pip might point to a different Python 3 installation than the one you’re using.

The safest approach: Always use python -m pip instead of bare pip:

python -m pip install requests

This guarantees you’re installing the package for the exact Python interpreter that python points to. If you run your script with python3, use:

python3 -m pip install requests

How to verify which Python pip is using

Check where pip is installing packages:

pip --version

Output:

pip 24.0 from /usr/lib/python3.11/site-packages/pip (python 3.11)

Now check which Python you’re running:

python --version
python3 --version

If pip --version says Python 3.11 but python --version says Python 3.12, that’s your problem. The package is installed for 3.11 but you’re running 3.12.

Use python3.12 -m pip install requests to install for the correct version.

Fix 3: Activate Your Virtual Environment

If you created a virtual environment, packages installed inside it are only available when the environment is active. Running pip install outside the venv installs packages globally (or to your user site-packages), and your venv won’t see them.

venv (built-in)

# Create (if you haven't already)
python -m venv .venv

# Activate
# Linux/macOS:
source .venv/bin/activate

# Windows (Command Prompt):
.venv\Scripts\activate.bat

# Windows (PowerShell):
.venv\Scripts\Activate.ps1

# Now install
pip install requests

When the venv is active, your shell prompt will show the environment name (e.g., (.venv)). If you don’t see it, the venv isn’t active. If your venv specifically is stuck or pointing at the wrong interpreter, see Fix: python ModuleNotFoundError in venv.

Conda

# Activate your environment
conda activate myenv

# Install
conda install requests
# or
pip install requests

Poetry

Poetry manages its own virtual environment. Use poetry run to run commands inside it:

poetry add requests
poetry run python app.py

Or activate the shell:

poetry shell
python app.py

Common mistake: installing before activating

If you run pip install requests without activating your venv first, the package goes to the system Python. Then when you activate the venv and run your script, Python looks in the venv’s site-packages and doesn’t find it. Always activate first, then install.

Fix 4: Fix the Module/Import Name

Some Python packages have a pip install name that’s different from the import name. This is one of Python packaging’s most confusing quirks.

For example:

pip install Pillow
# Wrong -- the package is called Pillow, but the import is PIL
import Pillow  # ModuleNotFoundError

# Correct
from PIL import Image

Common Package Name Mismatches

pip install nameimport nameNotes
PillowPILPillow is the maintained fork of PIL
opencv-pythoncv2Also applies to opencv-contrib-python
scikit-learnsklearn
python-dateutildateutil
beautifulsoup4bs4
python-dotenvdotenv
PyYAMLyaml
pymysqlpymysqlInstall name is PyMySQL (case differs)
attrsattrimport attr (though import attrs also works since v22)
google-cloud-storagegoogle.cloud.storageNamespace package
python-magicmagic
FakerfakerCase difference

If you get ModuleNotFoundError, check the package’s PyPI page or documentation for the correct import name. The install name and import name are not always the same.

Fix 5: Check Python Version Compatibility

Some packages drop support for older Python versions. Others only support Python 3 and won’t install on Python 2.

Check the package’s required Python version on PyPI:

pip install requests==

This will show an error listing all available versions. Or check the project’s PyPI page for the “Requires Python” field.

If you need a specific Python version:

# Check your version
python --version

# Install a specific package version that supports your Python
pip install numpy==1.24.0

For example, NumPy 2.0+ requires Python 3.9+. If you’re on Python 3.8, you need to install an older NumPy version:

pip install "numpy<2"

Edge Cases

Relative import errors

If you see ImportError: attempted relative import with no known parent package alongside a relative import (like from .utils import helper), the issue is that you’re running the file directly instead of as part of a package.

# my_package/main.py
from .utils import helper  # Fails if you run: python my_package/main.py

Relative imports only work when the file is imported as part of a package. Run it as a module instead:

# Wrong
python my_package/main.py

# Correct
python -m my_package.main

Missing __init__.py

In Python 3, packages can work without __init__.py (namespace packages). But some tools and configurations still require it. If your project structure looks like this:

my_project/
├── my_package/
│   ├── module_a.py
│   └── module_b.py
└── main.py

And from my_package import module_a fails, add an __init__.py file to the package directory:

touch my_package/__init__.py

The file can be empty. Its presence tells Python that the directory is a package.

PYTHONPATH

If your module is in a non-standard location, Python won’t find it unless you tell it where to look. You can add directories to the search path via the PYTHONPATH environment variable:

# Linux/macOS
export PYTHONPATH="/path/to/your/modules:$PYTHONPATH"
python app.py

# Windows (PowerShell)
$env:PYTHONPATH = "C:\path\to\your\modules;$env:PYTHONPATH"
python app.py

sys.path manipulation

You can also modify the search path at runtime in your script:

import sys
sys.path.insert(0, '/path/to/your/modules')
import your_module

This works but is fragile. If you need this in production code, it usually means your project structure needs fixing. Prefer installing your package in development mode instead:

pip install -e .

This requires a pyproject.toml (or setup.py) in your project root. It installs your project as a package so all its modules are importable from anywhere within the Python environment.

Still Not Working?

Your IDE is using the wrong Python interpreter

This is extremely common. Your terminal might use one Python while your IDE uses a different one.

VS Code: Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and search for “Python: Select Interpreter”. Choose the interpreter that has your packages installed. If you’re using a virtual environment, select the Python inside .venv/bin/python (or .venv\Scripts\python.exe on Windows).

PyCharm: Go to SettingsProjectPython Interpreter. Verify it points to the correct environment. If your venv isn’t listed, click the gear icon and add it.

pip install —user

If you can’t install packages globally (no admin/root access), use the --user flag:

pip install --user requests

This installs the package to your user site-packages directory (e.g., ~/.local/lib/python3.11/site-packages/ on Linux). Make sure this directory is in your Python’s sys.path:

import site
print(site.getusersitepackages())

Note that --user is silently disabled when a venv is active. Inside a venv it has no effect because the user site is suppressed by design.

Check site-packages location

If you’ve installed the package but Python still can’t find it, verify where Python is looking:

import sys
print(sys.path)

And check where pip installed the package:

pip show requests

The Location field in the output should match one of the paths in sys.path. If it doesn’t, you’re running a different Python than the one pip installed to. If you have a venv whose interpreter does not match the project’s intended Python version, see Fix: Python virtualenv wrong Python.

Conda vs pip conflicts

If you use Conda, mixing conda install and pip install can cause issues. Conda manages its own environment, and pip might install packages to a different location than Conda expects.

Best practice:

  1. Install as much as possible with conda install first.
  2. Use pip install only for packages not available through Conda.
  3. Never run pip install outside an active Conda environment.

If things are broken, recreate the environment:

conda deactivate
conda env remove -n myenv
conda create -n myenv python=3.11
conda activate myenv
conda install numpy pandas  # conda first
pip install some-other-package  # pip for the rest

Docker and containers

If you’re getting this error inside a Docker container, make sure your Dockerfile installs the dependencies:

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

A common mistake is copying the code before installing dependencies, then modifying requirements.txt without rebuilding the image. Docker’s layer caching means the RUN pip install step won’t re-run unless requirements.txt changed.

PEP 668 blocked your install silently

If you ran pip install requests on a Debian 12 or Ubuntu 23.04+ system Python and got an externally-managed-environment error, the command may have failed without you noticing — your terminal moves on, and then import requests raises ModuleNotFoundError. Confirm by rerunning the install and reading the full output. The fix is to switch to a venv:

python3 -m venv .venv
source .venv/bin/activate
pip install requests

Do not reach for --break-system-packages unless you specifically want to install into the OS’s Python. That flag exists to let the OS package manager bypass the lock, not for everyday use.

A namespace package shadowed the real one

If you have a local file or directory named the same as the package you are trying to import — for example, a file called requests.py in your project root — Python imports yours instead of the installed package, then fails when it can’t find the expected attributes. Rename your local file and delete any __pycache__ directories nearby.

pip install succeeded but no files actually landed

On some systems, pip install --user falls back silently when the install target is not writable, leaving you with a “success” message and no installed files. Look at the install location reported by pip show and verify the files are actually there with ls. If the directory is empty, rerun the install with -v for verbose output to see what happened.


Related: If you’re hitting a similar error in Node.js, see Fix: Error Cannot find module (Node.js).

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles