ModuleNotFoundError: No Module Named `_curses`

This error means the Python interpreter you are running does not include its compiled _curses extension. On Windows, install the Windows-compatible curses package into the same Python environment; on Linux or macOS, repair the Python installation or rebuild the custom Python interpreter that is missing curses support.

Use the traceback path and the Python executable, not the application that failed, to choose the fix.

Symptom in the Traceback Likely Cause Fix
Windows path and import curses fails Windows Python has no native curses implementation installed Install windows-curses with that Python interpreter
/usr/lib/python3.../curses/ on Linux The distro Python curses package or library files are missing or damaged Reinstall the distro’s Python curses support
/usr/local/lib/python3.../curses/ on Linux A source-built Python was compiled without ncurses headers Install development headers and rebuild Python
pip succeeds but import curses still fails The package was installed into a different interpreter or virtual environment Use python -m pip from the interpreter that runs the app
ncurses is installed but _curses is missing Python itself was built or packaged without its _curses extension Repair or replace that Python runtime

What the _curses Error Means

Python’s curses module is a standard-library wrapper for terminal user interfaces. It is not usually an application dependency that can be fixed by installing a similarly named package from PyPI.

When code runs:

import curses

Python loads its standard-library curses/__init__.py file. That file then attempts this import:

from _curses import *

_curses is a compiled extension that ships with a complete CPython build. If it is absent, Python raises:

ModuleNotFoundError: No module named '_curses'

The package to repair is determined by the interpreter in the traceback, not by the project that happens to import curses.

For example, a traceback under /usr/local/lib/python3.6/ commonly points to a separately compiled Python rather than the operating system’s managed Python. A traceback under a virtual environment may inherit the limitation from the Python installation that created that environment.

The reported troubleshooting attempt was:

pip3 install curses-util

That package-install attempt left the _curses error unchanged in the reported case because it does not add CPython’s missing native _curses extension.

How to Fix _curses Without Installing Random Packages

Identify the failing interpreter, then install or repair its matching curses support before rerunning the original program.

Step 1: Identify the Python Interpreter That Fails

First, run the checks with the same command context that starts your program. If you activated a virtual environment before running the application, keep it activated.

On Windows, run:

py -c "import sys; print(sys.executable); print(sys.version)"

Then test curses directly:

py -c "import curses; print(curses.__file__)"

On Linux or macOS, run:

python3 -c "import sys; print(sys.executable); print(sys.version)"

Then test curses:

python3 -c "import curses; print(curses.__file__)"

Also check which interpreter owns pip:

python3 -m pip -V

The path shown by python3 -m pip -V should refer to the same Python installation shown by sys.executable. If it does not, installing packages with that pip will not affect the interpreter that fails.

If the error happens only when launching a command-line tool, inspect the traceback. The Python paths in it are more useful than the location of the tool’s executable wrapper.

Step 2: Repair It on Windows 11

Windows does not include Unix ncurses libraries, so CPython’s standard curses support needs a Windows compatibility package. Install it into the exact Python environment that runs your application:

py -m pip install --upgrade windows-curses

Then verify the import:

py -c "import _curses, curses; print(curses.__file__)"

If your project uses a virtual environment, activate that environment first and use python, not the global py launcher:

python -m pip install --upgrade windows-curses

Test the import in the virtual environment:

python -c "import _curses, curses; print(curses.__file__)"

The Windows-compatible package is named windows-curses. A package listing in the reported case showed windows-curses version 2.1.0; package versions change, so confirm the version installed for your interpreter with:

py -m pip show windows-curses

After the import works, rerun the original script or command from the same terminal and environment.

Step 3: Repair a Linux Distribution Python

If the failing interpreter is a system-managed Python, repair it through the operating system package manager.

On Debian or Ubuntu, use the distribution package manager to repair the affected Python installation:

sudo apt update
sudo apt install python3-curses

Test the repaired interpreter:

python3 -c "import _curses, curses; print(curses.__file__)"

On Fedora, RHEL, Rocky Linux, or similar systems, repair the affected Python installation through the distribution package manager:

sudo dnf reinstall python3-libs

Then test:

python3 -c "import _curses, curses; print(curses.__file__)"

If the affected Python runtime is not installed, restore it through the distribution package manager:

sudo dnf install python3

A native ncurses package being present is not enough by itself. Python must also have been packaged or compiled with the _curses extension enabled. A reported SailfishOS system had ncurses installed and current while its Python 3.8 interpreter still could not import _curses (issue details).

Finish by running the same import test through the interpreter your application uses. If your application uses a virtual environment, recreate that environment after the base interpreter works.

Step 4: Rerun the Original Program

Once the direct import works, rerun the command that originally failed. For a script, that may be:

python3 your_script.py

For an activated virtual environment, use:

python your_script.py

If the application still fails but the standalone import works, compare the Python executable shown by sys.executable with the one in the application traceback. You are likely launching the app with a different interpreter, such as an old virtual environment, a globally installed console script, or another Python version on PATH.

Rebuild Python When a Custom Build Is Missing Curses

A Python installed under /usr/local, managed by a version manager, or compiled from source can lack _curses if the ncurses header files were unavailable during configuration.

On Debian or Ubuntu, ensure compiler tools and ncurses development headers are available before rebuilding:

sudo apt update
sudo apt install build-essential libncurses-dev

In the existing Python source directory, clear the previous configuration and rebuild:

make distclean
./configure
make

Before installing, test the freshly built interpreter in that source directory:

./python -c "import _curses, curses; print(curses.__file__)"

If the test succeeds, install the new version without replacing the operating system’s python3 command:

sudo make altinstall

Use the versioned Python executable created by make altinstall when you recreate virtual environments or reinstall your application.

On Fedora-family systems, ensure ncurses development headers are available before rebuilding:

sudo dnf install gcc make ncurses-devel

Then rerun the configure, build, and import-test sequence from the Python source directory.

On macOS with a source-built Python, make the ncurses headers and libraries available during configuration:

brew install ncurses

Set the ncurses include and library paths before configuration:

export CPPFLAGS="-I$(brew --prefix ncurses)/include"
export LDFLAGS="-L$(brew --prefix ncurses)/lib"

Then rebuild Python with ./configure, make, and make altinstall, and confirm that the newly built interpreter can import both _curses and curses.

The Linux traceback reported at /usr/local/lib/python3.6/curses/__init__.py was traced to a self-compiled Python without curses support and missing ncurses development headers (project issue).

Virtual Environments, Containers, and Multiple Python Versions

A virtual environment does not manufacture a missing native standard-library extension. It uses the Python installation from which it was created.

After fixing the base interpreter, remove and recreate a project virtual environment if it was built from the broken Python:

rm -rf .venv
python3 -m venv .venv

Activate it on Linux or macOS:

source .venv/bin/activate

Then verify curses before reinstalling project dependencies:

python -c "import _curses, curses; print(curses.__file__)"

If the project has a requirements file, reinstall it after the import succeeds:

python -m pip install -r requirements.txt

For containers, test _curses inside the image rather than assuming the host’s Python setup applies. Minimal images can omit runtime libraries or use a different Python build. Add the required OS package during the image build, rebuild the image, and run the import test inside the resulting container.

I use a clean virtual environment for this check because it separates a broken base interpreter from packages installed for one project.

How to Prevent the Error

Use the Python interpreter explicitly when installing dependencies:

python -m pip install -r requirements.txt

This avoids the common mismatch where pip installs into one Python version while the application launches with another.

For Linux development machines, prefer the operating system’s Python package unless you need a custom build. If you compile CPython yourself, install ncurses development headers before running ./configure, then test this import before building project environments:

python3 -c "import _curses, curses; print('curses is available')"

For Windows projects that use terminal interfaces, add windows-curses to the project’s Windows-specific dependency setup so new environments receive it automatically.

Frequently Asked Questions

Why does import curses fail when _curses is the missing module?

curses is the public standard-library module, while _curses is its compiled implementation layer. The curses/__init__.py wrapper executes from _curses import *, so the error names _curses even though your code imported curses.

How do I fix No module named '_curses' on Windows 11?

Install windows-curses into the Python environment that runs the program:

python -m pip install --upgrade windows-curses

Then test it with python -c "import curses". If you have multiple Python versions, use the launcher for the same version used by the application, such as py -3.12 -m pip.

Does pip3 install curses-util fix the error?

No. The command pip3 install curses-util does not supply CPython’s compiled _curses extension, and the reported error remained after that installation attempt. Repair the Python runtime or install windows-curses on Windows instead.

Why is _curses missing even though ncurses is installed on Linux?

The installed ncurses library is only one part of the requirement. Python must have found the ncurses headers and built its _curses extension, or your distribution must provide that extension in its Python package. Reinstall the distribution’s Python curses package or rebuild the custom Python after installing libncurses-dev or ncurses-devel.

Can I install an old curses wheel manually?

Usually not. An older example, curses-2.2-cp36-cp36m-win32.whl, is specifically for CPython 3.6 and 32-bit Windows, as indicated by cp36 and win32 in its filename. It is not appropriate for a 64-bit Python installation or a newer Python version; use windows-curses and let python -m pip select a compatible distribution.

What should I do after import curses works?

Rerun the original command from the same terminal, virtual environment, or container where you performed the successful test. If it fails again, print sys.executable from both contexts and correct the interpreter mismatch before reinstalling anything else.