2026, Jan 05 09:00
How to fix uWSGI ModuleNotFoundError for Flask-WTF: use the correct Python virtualenv
Fix uWSGI ModuleNotFoundError: No module named 'flask_wtf'. Learn why interpreter mismatches happen and how to point uWSGI to the correct Python virtualenv.
uWSGI reports ModuleNotFoundError: No module named 'flask_wtf' even though Flask-WTF appears in pip freeze inside the project’s virtualenv. This happens when the application server runs a different Python environment than the one where dependencies are installed.
Minimal reproduction
The failure surfaces as soon as code touches Flask-WTF. A trivial Flask app is enough to trigger it when uWSGI is not pointed to the correct virtualenv.
from flask import Flask
from flask_wtf import FlaskForm
from wtforms import StringField
def build_app():
svc = Flask(__name__)
svc.config["SECRET_KEY"] = "dev" # required by Flask-WTF
class ProfileForm(FlaskForm):
nickname = StringField("nickname")
@svc.route("/")
def home():
return "OK"
return svc
Under uWSGI, this import can fail with ModuleNotFoundError if uWSGI uses a Python interpreter that doesn’t see packages installed in your virtualenv.
What’s really going on
The symptoms make the mismatch clear. Outside the virtualenv, pip is not even on PATH on NixOS; inside the virtualenv, pip freeze lists Flask-WTF. So the project dependencies live in /var/www/folder/folder_env, but uWSGI is launching the app with a different interpreter that knows nothing about that environment. Different interpreters do not share site-packages, therefore flask_wtf cannot be resolved.
In short: uWSGI must be explicitly told to use the same virtualenv that holds your Flask and Flask-WTF installations.
Fix: tell uWSGI which virtualenv to use
Point uWSGI to the project’s virtualenv. Add the virtualenv directive to your uWSGI configuration:
virtualenv = "/var/www/folder/folder_env"
After reloading or restarting uWSGI, it will run the app with the interpreter from that virtualenv, and the import from flask_wtf will succeed because the package is available there.
Verifying the interpreter alignment
When working with multiple Python versions and environments, it’s easy to install a package for one interpreter while running code with another. To keep everything aligned, install dependencies via the exact interpreter that will execute the app, and verify which interpreter is actually in use at runtime.
# Install with the specific interpreter version
python3.12 -m pip install Flask-WTF
# Or install using the venv's python directly
/var/www/folder/folder_env/bin/python -m pip install Flask-WTF
Inside the application you can also confirm which Python is running:
import sys
print(sys.executable)
If this path matches /var/www/folder/folder_env/bin/python, your uWSGI process is using the intended environment.
Why this matters
Production app servers like uWSGI are separate processes from your development shell. Assuming they “inherit” your activated virtualenv is a common source of deployment bugs. Explicitly binding the app server to the correct virtualenv eliminates a whole class of import errors, prevents mixing global and project-level packages, and makes environments reproducible—especially on NixOS, where system packages are intentionally isolated.
Takeaways
If uWSGI can’t find a Python package that is clearly installed in your virtualenv, it’s almost always an interpreter mismatch. Configure uWSGI with the virtualenv path, restart it, and confirm the interpreter with sys.executable. When installing packages, drive pip through the exact Python you use to run the app, either via python3.12 -m pip or the full path to the venv’s python. Once all three points align—installation interpreter, runtime interpreter, and uWSGI configuration—the ModuleNotFoundError disappears.