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: 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: Flask Route Returns 404 Not Found
How to fix Flask routes returning 404 — trailing slash redirect, Blueprint prefix issues, route not registered, debug mode, and common URL rule mistakes.
Fix: Git Keeps Asking for Username and Password
How to fix Git repeatedly prompting for credentials — credential helper not configured, HTTPS vs SSH, expired tokens, macOS keychain issues, and setting up a Personal Access Token.
Fix: pandas merge() Key Error and Duplicate Columns (_x, _y)
How to fix pandas merge and join errors — KeyError on merge key, duplicate _x/_y columns, unexpected row counts, suffixes, and how to validate merge results.