Fix 'ModuleNotFoundError' in a Cron Python Job
If a Python script works in your terminal but fails with ModuleNotFoundError under cron, cron is using a different Python than you are. The fix is to call the exact interpreter that has the packages installed — usually your virtualenv's python.
Why it happens
Your shell uses a virtualenv or a pyenv/nvm-style Python where the packages are installed. Cron runs bare python3 from /usr/bin, which doesn't have them — so imports fail.
The fix: call the venv interpreter
Find the right Python with which python while your environment is active, then use that full path in cron:
*/30 * * * * /home/user/project/venv/bin/python /home/user/project/job.py >> /home/user/project/job.log 2>&1
If it's your own module that's missing
Set PYTHONPATH so imports of sibling files resolve: */30 * * * * PYTHONPATH=/home/user/project /home/user/project/venv/bin/python /home/user/project/job.py. Or cd into the project first.
Confirm with the log
The redirect captures the traceback. The last line of a ModuleNotFoundError names the missing package — check it is installed in the interpreter cron actually calls.
FAQ
Why does my Python cron job say ModuleNotFoundError but works manually?
Cron runs /usr/bin/python3, not your virtualenv Python that has the packages. Call the venv interpreter directly, e.g. /path/venv/bin/python /path/job.py.
How do I fix ModuleNotFoundError for my own module in cron?
Set PYTHONPATH to your project directory in the cron line, or cd into the project before running, so sibling imports resolve.
How do I find the right Python interpreter for cron?
Activate your environment and run 'which python'. Use that absolute path in the crontab instead of bare python3.