Troubleshooting¶
This guide helps you resolve common issues when using build.
Build fails with missing dependencies¶
Symptom: Build fails with errors like “ModuleNotFoundError” or “No module named ‘X’”.
Cause: Your build backend or its dependencies aren’t installed in the isolated environment.
Solution 1: Let build handle it automatically (default):
$ python -m build
Build will read your pyproject.toml and install all required dependencies.
Solution 2: If using --no-isolation, manually install dependencies:
$ pip install setuptools your-build-backend
$ python -m build --no-isolation
Build hangs or appears frozen¶
Symptom: Build command runs but produces no output for a long time.
Possible causes:
Waiting for authentication: If you’re using a private package index, build may be waiting for credentials.
See Corporate Environments for authentication setup.
Large download: Build backend dependencies are being downloaded.
Use
-vor-vvfor verbose output:$ python -m build -vv
Build backend is actually running: Some backends (especially for C extensions) can take time.
Check system monitor for CPU/disk activity to confirm work is happening.
SSL certificate verification failed¶
Symptom: Errors like “SSL: CERTIFICATE_VERIFY_FAILED” or “certificate verify failed”.
Cause: Your system doesn’t trust the SSL certificate of the package index.
Solution 1: Provide the CA certificate (recommended):
$ export PIP_CERT=/path/to/company-ca-bundle.crt
$ python -m build
Solution 2: Use build with virtualenv for better SSL support:
$ pip install build[virtualenv]
$ python -m build
Solution 3: For development only, disable verification (not recommended):
$ export PIP_TRUSTED_HOST=pypi.company.com
$ python -m build
See Corporate Environments for more details.
Permission denied errors¶
Symptom: “PermissionError” or “Access is denied” when creating directories or files.
Common causes:
Output directory is protected: The
dist/directory is owned by another user or process.Solution: Remove the directory first or use a different output location:
$ rm -rf dist/ $ python -m build
Or:
$ python -m build --outdir /tmp/my-build
Running inside a read-only directory: The source directory is on a read-only filesystem.
Solution: Copy the source to a writable location first.
Antivirus software: Some antivirus tools block Python from creating virtual environments.
Solution: Add Python and your project directory to antivirus exclusions.
Wheel is not compatible with this platform¶
Symptom: “is not a supported wheel on this platform” when trying to install the built wheel.
Cause: The wheel was built for a different Python version or platform.
Solution: Build on the same platform and Python version where you’ll install, or use cibuildwheel for multi-platform builds.
See build vs Other Tools for when to use cibuildwheel vs build.
Build succeeds but package is missing files¶
Symptom: After building, the package installs but is missing source files, data files, or modules.
Cause: Files aren’t included in the source distribution manifest.
Solution: The fix depends on your build backend:
For setuptools (setuptools documentation):
Add a MANIFEST.in file or use package_data in pyproject.toml:
[tool.setuptools.package-data]
mypackage = ["data/*.json", "templates/*.html"]
For hatchling (hatchling documentation):
Use the include and exclude options:
[tool.hatch.build.targets.wheel]
include = [
"src/**/*.py",
"src/**/*.json",
]
For flit (flit documentation):
Flit includes all files tracked by git by default. Ensure files are committed.
Test your sdist: Always verify the sdist contains all necessary files:
$ python -m build --sdist
$ tar -tzf dist/mypackage-1.0.0.tar.gz
ModuleNotFoundError in the built wheel¶
Symptom: The wheel installs successfully, but importing the package fails with “ModuleNotFoundError”.
Cause: The package structure in your source doesn’t match what the build backend expects.
Common issues:
Missing ``__init__.py``: Ensure every package directory has an
__init__.pyfile (not needed for namespace packages).Wrong directory structure: For src-layout, ensure you have
src/packagename/not justpackagename/.Not configuring package discovery: Tell your build backend where to find packages.
For setuptools with src-layout:
[tool.setuptools.packages.find] where = ["src"]
Version conflict between build dependencies¶
Symptom: Build fails with errors about conflicting package versions.
Cause: Build dependencies have incompatible version requirements.
Solution 1: Update your build backend and its dependencies:
$ pip install --upgrade pip setuptools
Then try building again:
$ python -m build
Solution 2: If using --no-isolation, create a fresh virtual environment:
$ python -m venv fresh-env
$ source fresh-env/bin/activate # On Windows: fresh-env\\Scripts\\activate
$ pip install build
$ python -m build
The isolated build (without --no-isolation) avoids this issue by creating a clean environment each time.
Build works locally but fails in CI¶
Common causes:
Different Python versions: CI may use a different Python version than your local environment.
Solution: Specify Python version in CI config, test locally with that version.
Missing system dependencies: C extensions may need system libraries.
Solution: Install required libraries in CI before building:
# GitHub Actions example - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y libffi-dev
File path issues: Windows vs Unix path separators.
Solution: Use
pathlib.Pathinpyproject.tomlconfigurations and build scripts.Git not available: Some backends use git for version detection.
Solution: Ensure git is installed in CI, or use explicit versioning in
pyproject.toml.
See CI/CD Integration for CI-specific guidance.
Catching deprecation warnings¶
To catch warnings from your build backend in CI:
$ PYTHONWARNINGS=error::DeprecationWarning python -m build
Or for setuptools specifically:
$ PYTHONWARNINGS=error:::setuptools.config.setupcfg python -m build
This fails the build if deprecated features are used, helping you catch issues early.
Build backend not found¶
Symptom: “Backend ‘X’ is not available” or “No module named ‘X’”.
Cause: The build backend specified in pyproject.toml isn’t installed.
Solution: This shouldn’t happen with isolated builds (the default). If you see this:
Check your
pyproject.toml[build-system]section is correct:[build-system] requires = ["hatchling"] build-backend = "hatchling.build"
If using
--no-isolation, install the backend:$ pip install hatchling $ python -m build --no-isolation
No build-system section in pyproject.toml¶
Symptom: Build succeeds but you’re not sure which backend is being used.
Cause: No [build-system] section is specified in pyproject.toml.
Solution: As recommended in PEP 517, if no backend is specified, build will fallback to
setuptools.build_meta:__legacy__. This is for backward compatibility with older projects. For new projects,
explicitly specify your build backend:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
This makes your build configuration explicit and avoids relying on the fallback behavior.
Build installed in user site-packages¶
Symptom: Virtual environment creation fails with errors like “executable /usr/local/bin/python missing”.
Cause: When build is installed in the user site-packages (pip install --user build), it can interfere with
isolated environment creation.
Solution: Install build in a virtual environment instead:
$ python -m venv build-env
$ source build-env/bin/activate # On Windows: build-env\\Scripts\\activate
$ pip install build
$ python -m build
Or use pipx to install build in isolation:
$ pipx install build
$ pipx run build
Package name has dashes but wheel has underscores¶
Symptom: Your package is named my-package but the wheel is my_package-1.0.0-py3-none-any.whl.
This is expected behavior: According to PEP 427, wheel filenames normalize package names by replacing dashes with underscores. This is not a bug.
Your users can still install with either name:
$ pip install my-package # Works
$ pip install my_package # Also works
The package metadata preserves your original name, only the filename is normalized.
Getting more information¶
Verbose output¶
Use -v or -vv for detailed output:
$ python -m build -v # Verbose
$ python -m build -vv # Very verbose
This shows what build is doing and can help identify where failures occur.
Check your configuration¶
Verify your pyproject.toml is valid:
$ python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb')))"
Test the build backend directly¶
You can test if your build backend works independently:
$ pip install your-build-backend
$ python -m your_build_backend
Preserve build logs and temporary directories¶
By default, build cleans up the temporary build directory after completion. To control where the temporary directory is created (useful for debugging or placing it on a specific filesystem):
$ TMPDIR=/tmp/debug-build python -m build
The build will create its temporary environment inside /tmp/debug-build. The directory is automatically cleaned up
after a successful build, but persists if the build fails, allowing you to inspect the environment for debugging. On
Windows, use TEMP instead of TMPDIR:
$ set TEMP=C:\debug-build
$ python -m build
To see backend logs in real-time, use verbose output:
$ python -m build -vv
This shows all output from the build backend, including compilation logs for C extensions and detailed error messages.
Still having issues?¶
If your issue isn’t covered here:
Check the issue tracker for similar problems
Enable verbose output (
-vv) and include the full output when reporting issuesInclude your
pyproject.tomland Python version when asking for help
See also¶
Corporate Environments for proxy, SSL, and authentication issues
CI/CD Integration for CI/CD-specific problems
Environment Variables for environment variables that affect build