Fix: Python venv Using Wrong Python Version
Quick Answer
How to fix Python virtual environments using the wrong Python version — venv picking system Python instead of pyenv, specifying the interpreter path, and verifying the active environment.
The Error
You create a virtual environment expecting Python 3.11 but get 3.9 (or another version):
python -m venv .venv
source .venv/bin/activate
python --version
# Python 3.9.7 ← Expected 3.11Or you install a package that requires Python 3.10+ but it fails:
ERROR: Package 'some-package' requires a different Python: 3.9.7 not in '>=3.10'Or pyenv shows the right version but the venv still uses the system Python:
pyenv version
# 3.11.8 (set by /home/user/project/.python-version)
python -m venv .venv
source .venv/bin/activate
python --version
# Python 3.9.18 ← Still wrongOr after activating the venv, which python points outside the venv:
which python
# /usr/bin/python3 ← Should be /home/user/project/.venv/bin/pythonWhy This Happens
Virtual environments are created using whichever Python binary runs python -m venv. The resulting environment is permanently tied to that specific Python binary:
pythoncommand resolves to the wrong binary —pythonmay point to Python 3.9 whilepython3orpython3.11points to a newer version.- pyenv shims not in PATH or not initialized — pyenv works by inserting shims at the beginning of
PATH. If pyenv’s init isn’t in your shell profile, the shims don’t activate and the system Python is used instead. - Shell profile not reloaded — you installed a new Python version but haven’t restarted your shell or run
source ~/.bashrc. python -m venvcalled before activating pyenv — if you runpython -m venv .venvin a script or CI pipeline without first sourcing pyenv, it uses the system Python.- Conda base environment active — Conda’s base environment may intercept
pythonand return its own version, regardless of pyenv settings. - venv already created with the wrong Python — once a venv is created, its Python version is fixed. Deleting and recreating is the only way to change it.
Fix 1: Specify the Python Binary Explicitly
The most reliable fix is to call the exact Python binary you want when creating the venv:
# Use the full path to the desired Python
/usr/bin/python3.11 -m venv .venv
# Or use the versioned command directly
python3.11 -m venv .venv
python3.10 -m venv .venv
# Verify the result
source .venv/bin/activate
python --version # Should now show the correct versionFind available Python binaries:
# List Python binaries on the system
ls /usr/bin/python*
ls /usr/local/bin/python*
# Use 'which' to find a specific version
which python3.11
which python3.12Fix 2: Fix pyenv Not Working
If you use pyenv but the venv still uses the system Python, fix the pyenv initialization:
# Check if pyenv is properly initialized
pyenv version
# If this fails or shows 'system', pyenv is not active
# Check if pyenv shims are in PATH
echo $PATH | tr ':' '\n' | grep pyenv
# Should see something like: /home/user/.pyenv/shims
# Initialize pyenv in your shell profile
cat ~/.bashrc # or ~/.zshrc, ~/.bash_profile
# Should contain:
# export PYENV_ROOT="$HOME/.pyenv"
# export PATH="$PYENV_ROOT/bin:$PATH"
# eval "$(pyenv init -)"Add pyenv initialization to your shell profile:
# For bash — add to ~/.bashrc or ~/.bash_profile
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
# For zsh — add to ~/.zshrc
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
source ~/.zshrcAfter initializing pyenv, verify it works:
# Verify pyenv is active
pyenv version
# 3.11.8 (set by /home/user/project/.python-version)
# Check which python pyenv resolves to
pyenv which python
# /home/user/.pyenv/versions/3.11.8/bin/python
# Now create the venv — it will use pyenv's Python
python -m venv .venv
source .venv/bin/activate
python --version
# Python 3.11.8 ✓Install the Python version you need with pyenv:
# List available versions
pyenv install --list | grep "3.11"
# Install a specific version
pyenv install 3.11.8
# Set it globally (all projects)
pyenv global 3.11.8
# Set it for the current project only (creates .python-version file)
pyenv local 3.11.8
# Verify
python --version # 3.11.8Fix 3: Delete and Recreate the venv
Once a venv is created, its Python version is baked in and cannot be changed. Delete and recreate it with the correct Python:
# Deactivate the current venv if active
deactivate
# Delete the venv
rm -rf .venv
# Recreate with the correct Python
python3.11 -m venv .venv
# Or with pyenv active:
pyenv local 3.11.8
python -m venv .venv
# Activate and verify
source .venv/bin/activate
python --version
# Python 3.11.8 ✓
# Reinstall dependencies
pip install -r requirements.txtFix 4: Fix the PATH Order
If multiple Python installations conflict, PATH order determines which python command is found first:
# See the full resolution order
echo $PATH | tr ':' '\n'
# See which python is found
which python
which python3
which python3.11
# If pyenv shims aren't first, fix PATH order
# pyenv shims must come before /usr/bin
export PATH="$HOME/.pyenv/shims:$HOME/.pyenv/bin:$PATH"Check for Conda interference:
# If Conda is active, it prepends its bin directory to PATH
conda info
# Shows: active environment
# Deactivate Conda base environment
conda deactivate
# Or configure Conda to not activate base by default
conda config --set auto_activate_base falsemacOS — Homebrew Python conflicts:
# Homebrew installs Python at:
ls /opt/homebrew/bin/python* # Apple Silicon
ls /usr/local/bin/python* # Intel
# Set up PATH to prefer pyenv over Homebrew
# In ~/.zshrc:
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH" # pyenv first
eval "$(pyenv init -)"
# Homebrew's python3 comes after pyenv in PATHFix 5: Verify the Active venv
After activating a venv, verify all Python-related commands resolve inside the venv:
source .venv/bin/activate
# All of these should point inside .venv/
which python
# /home/user/project/.venv/bin/python
which pip
# /home/user/project/.venv/bin/pip
python --version
# Python 3.11.8
pip --version
# pip 23.x.x from /home/user/project/.venv/lib/python3.11/site-packages/pip (python 3.11)
# Confirm the venv's Python binary and its version
python -c "import sys; print(sys.executable, sys.version)"
# /home/user/project/.venv/bin/python 3.11.8 (...)Check if the venv is actually active:
# The VIRTUAL_ENV environment variable is set when a venv is active
echo $VIRTUAL_ENV
# /home/user/project/.venv ← Active
# (empty) ← Not active
# The prompt usually shows the venv name
# (.venv) user@host:~/project$ ← ActiveFix 6: Use python -m venv with a Specific Version in CI/CD
In CI/CD pipelines, always specify the exact Python version to avoid using whatever is installed by default:
# GitHub Actions
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11' # Exact version — not 'python3' or '3.x'
- name: Create venv
run: python -m venv .venv # Uses the Python set by setup-python
- name: Install dependencies
run: |
source .venv/bin/activate
pip install -r requirements.txt# GitLab CI
test:
image: python:3.11-slim # Pin the Python version in the Docker image
script:
- python --version # Verify
- python -m venv .venv
- source .venv/bin/activate
- pip install -r requirements.txtIn Docker:
# Pin the exact Python version in the base image
FROM python:3.11.8-slim
# This sets the default python command to 3.11.8
RUN python --version # Python 3.11.8
WORKDIR /app
COPY requirements.txt .
RUN python -m venv .venv && \
.venv/bin/pip install --no-cache-dir -r requirements.txt
# Use the venv's Python explicitly
CMD [".venv/bin/python", "app.py"]Fix 7: Use Poetry or uv for Automatic Version Management
Modern Python package managers handle Python version selection automatically:
Poetry:
# pyproject.toml — specify Python version constraint
[tool.poetry.dependencies]
python = "^3.11" # Requires Python 3.11 or higher# Poetry creates the venv with a compatible Python
poetry env use python3.11 # Explicitly set the Python version
poetry env info # Shows which Python Poetry is usinguv (modern, fast Python package manager):
# uv automatically finds and uses the right Python
uv venv --python 3.11 .venv # Create venv with Python 3.11
uv venv --python /path/to/python # Or use a specific binary
# Or in pyproject.toml
# [project]
# requires-python = ">=3.11"
# Then:
uv venv # uv selects a compatible Python automaticallyStill Not Working?
Check if the venv’s pyvenv.cfg shows the right version:
cat .venv/pyvenv.cfg
# home = /usr/bin ← Where the Python was found (wrong if not 3.11)
# version = 3.9.7 ← The Python version (wrong)
# version_info = 3.9.7.final.0If it shows the wrong version, the venv must be recreated.
Check for a .python-version file in a parent directory — pyenv reads .python-version from the current directory up to the root. A .python-version in a parent directory may override your local settings:
# Find all .python-version files from current dir upward
ls -la .python-version 2>/dev/null || echo "Not here"
ls -la ../.python-version 2>/dev/null || echo "Not in parent"
# The effective pyenv version
pyenv version
# Shows which .python-version file is controlling the versionRestart your shell after modifying shell profile files. Changes to ~/.bashrc, ~/.zshrc, or ~/.bash_profile don’t take effect until you start a new shell session or run source ~/.bashrc.
For related Python environment issues, see Fix: Python ModuleNotFoundError (venv) and Fix: pip No Matching Distribution Found.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: uv Not Working — Command Not Found, Python Version Error, and Lock File Conflicts
How to fix uv errors — uv command not found after install, no Python interpreter found, uv run vs activate confusion, uv.lock merge conflicts, uv pip vs uv add, migrating from pip and Poetry, and workspace resolution failures.
Fix: Poetry Dependency Conflict (SolverProblemError / No Solution Found)
How to fix Poetry dependency resolution errors — SolverProblemError when adding packages, conflicting version constraints, how to diagnose dependency trees, and workarounds for incompatible packages.
Fix: Apache Airflow Not Working — DAG Not Found, Task Failures, and Scheduler Issues
How to fix Apache Airflow errors — DAG not appearing in UI, ImportError preventing DAG load, task stuck in running or queued, scheduler not scheduling, XCom too large, connection not found, and database migration errors.
Fix: Dash Not Working — Callback Errors, Pattern Matching, and State Management
How to fix Dash errors — circular dependency in callbacks, pattern matching callback not firing, missing attribute clientside_callback, DataTable filtering not working, clientside JavaScript errors, Input Output State confusion, and async callback delays.