Skip to content
Nilay Kabariya

Entry No.064·Fixes·Updated ·7 min read

Fix: Microsoft Visual C++ 14.0 or greater is required

pip install fails on Windows asking for Microsoft C++ Build Tools. Four causes reproduced, Failed building wheel for pyyaml fixed, and when Build Tools help.

by Nilay#python#windows#pip#dockerFIXED

The error, verbatim

Jump to the fix ↓
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
ERROR: Failed building wheel for msgpack
✓ Reproduced on Windows 11 Pro (no compiler); GitHub windows-latest (Build Tools, MSVC 14.51); GitHub ubuntu-latest

Tested on

Python
3.14.5 64-bit, 3.14.8 32-bit, 3.15.0, 3.15.2; 3.15 and 3.14 Docker images (Linux)
PyYAML
6.0.3, 6.0.1, 5.4.1
pip
26.1.1 / 26.2.1 / 26.2.2
OS
Windows 11 Pro (no compiler); GitHub windows-latest (Build Tools, MSVC 14.51); GitHub ubuntu-latest
Contents
  1. First: find out whether a wheel exists01
  2. 1. A pinned version that’s older than your Python02
  3. 2. Your Python is newer than the package03
  4. 3. 32-bit Python04
  5. 4. PIP_NO_BINARY or –no-binary forces a build05
  6. What about installing Build Tools?06
  7. Failed building wheel for pyyaml07
  8. How this was tested08

pip asks for a C++ compiler when it can’t find a ready-made build of a package (a wheel) for your exact Python, and falls back to compiling the source code. Windows doesn’t come with a compiler, so the build stops here. The last Failed building wheel for … line names the package.

The message makes it sound like the fix is installing Build Tools. Usually it isn’t. In most cases a wheel exists, and something is stopping pip from using it. I reproduced four causes on a Windows 11 PC without a compiler:

What’s going on Example that failed
A pinned version that’s older than your Python pyyaml==6.0.1, msgpack==1.0.7, regex==2023.12.25 on Python 3.14
Your Python is newer than the package pyyaml on Python 3.15
32-bit Python pyyaml, psutil on 32-bit Python 3.14
Something forces source builds PIP_NO_BINARY=:all:

If your error ends in ERROR: Failed building wheel for pyyaml, PyYAML has its own fix that needs no compiler: see Failed building wheel for pyyaml.

First: find out whether a wheel exists

Ask pip to download only wheels for the version in the error, with nothing else:

pip download msgpack==1.0.7 --only-binary :all: --no-deps -d dl

If there’s no wheel for your Python, the error lists the versions that do have one:

ERROR: Could not find a version that satisfies the requirement msgpack==1.0.7 (from versions: 1.1.2, 1.2.0rc1, 1.2.0, 1.2.1, 1.2.2, 1.2.3)

1. A pinned version that’s older than your Python

The most common cause. A requirements.txt written a year ago pins msgpack==1.0.7. That release only shipped wheels for the Pythons that existed back then. On Python 3.14 there’s nothing to download, so pip compiles it:

error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
ERROR: Failed building wheel for msgpack

pyyaml==6.0.1 and regex==2023.12.25 failed the same way on 3.14, while the latest pyyaml installed straight away.

Let pip pick a newer version that has a wheel:

pip install "msgpack>=1.0.7"

In requirements.txt, change == to >= for that package (or pin one of the versions the check above listed).

2. Your Python is newer than the package

A brand-new Python has no wheels at first. PyYAML 6.0.3, the latest release, has Windows wheels up to Python 3.14. On Python 3.15.0, pip install pyyaml compiled it and failed with the same error. So did transformers, because it depends on PyYAML.

Create the project’s environment with the previous Python. With the Python install manager:

py -V:3.14 -m venv .venv

For PyYAML only, there’s also $env:PYYAML_FORCE_LIBYAML = "0", which builds it without the C part. Failed building wheel for pyyaml below has the details, including what you lose without it.

3. 32-bit Python

Many packages only publish 64-bit Windows wheels. On a 32-bit Python, the newest pyyaml and psutil both tried to compile and failed with this error, though both install from wheels on 64-bit Python. pandas failed with a different message for the same reason:

..\meson.build:2:0: ERROR: Could not find C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe

Check which one you have:

python -c "import platform; print(platform.architecture()[0])"

If that prints 32bit, install the 64-bit Python and make the environment with it:

py install 3.14
py -V:3.14 -m venv .venv

4. PIP_NO_BINARY or –no-binary forces a build

PIP_NO_BINARY=:all: (or --no-binary :all: in a command, a pip.ini or a CI file) tells pip never to use wheels. Then even packages with a wheel get compiled. With it set, pip install pyyaml failed with the same error, and the package it was building at the time was Cython, pulled in as a build tool.

Check for it, and remove it:

pip config list
$env:PIP_NO_BINARY

What about installing Build Tools?

It works when the package’s source code still compiles on your Python. Often it doesn’t. On GitHub’s Windows runner, which has Visual Studio Build Tools installed (MSVC 14.51), I installed the same pinned versions on Python 3.14:

Install Build Tools only when you have to build that exact version, for example a package with no wheels at all. Pick “Desktop development with C++” in the installer.

Failed building wheel for pyyaml

The newest PyYAML, 6.0.3, has wheels for Python 3.8 to 3.14. It has none for Python 3.15, which came out on October 9, 2026, so on 3.15 every pip install pyyaml downloads pyyaml-6.0.3.tar.gz and tries to compile it. I got this error three ways: Python 3.15 on Windows, an old pinned version, and Docker slim images, where it doesn’t even print an error.

Python 3.15 on Windows

In a fresh Python 3.15.2 environment on Windows 11 without the Visual C++ build tools, pip install pyyaml failed:

  Downloading pyyaml-6.0.3.tar.gz (130 kB)
  Building wheel for pyyaml (pyproject.toml): finished with status 'error'
  error: subprocess-exited-with-error
      error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for pyyaml
error: failed-wheel-build-for-install
× Failed to build installable wheels for some pyproject.toml based projects
╰─> pyyaml

On Python 3.14, the same command downloaded pyyaml-6.0.3-cp314-cp314-win_amd64.whl and installed in a second. And pip install --only-binary=:all: pyyaml on 3.15 confirms there’s nothing ready-made: ERROR: Could not find a version that satisfies the requirement pyyaml (from versions: none).

PyYAML’s C part is optional. Its setup.py is written to fall back to pure Python when compiling fails, but on Windows a missing compiler raises a different error from the one that fallback catches, so the build stops instead.

Tell PyYAML not to build its C part. In PowerShell:

$env:PYYAML_FORCE_LIBYAML = "0"
pip install pyyaml

In cmd, use set PYYAML_FORCE_LIBYAML=0; in Git Bash, PYYAML_FORCE_LIBYAML=0 pip install pyyaml.

The variable is read by PyYAML’s own setup.py (PYYAML_FORCE_ plus the feature name, LIBYAML), so it only matters while pip is building PyYAML. You can remove it afterwards.

What you lose without the C part

Plain yaml.safe_load() and yaml.load() always use the pure-Python parser. The C version is only used when you ask for it by name, with CSafeLoader or CLoader.

On a 944 KB YAML file, with the same machine and the 3.14 wheel installed, yaml.load(text, Loader=yaml.CSafeLoader) was about 4.4 times faster than yaml.safe_load(text). The pure-Python build of PyYAML parsed it at the same speed as the wheel’s safe_load.

If your code or a library does ask for the C loader, the pure-Python build fails at that line:

AttributeError: module 'yaml' has no attribute 'CSafeLoader'. Did you mean '.SafeLoader' instead of '.CSafeLoader'?

from yaml import CSafeLoader gives an ImportError instead. Code that falls back, like getattr(yaml, "CSafeLoader", yaml.SafeLoader), keeps working, and yaml.__with_libyaml__ tells you which build you have: False for pure Python.

An old pin: PyYAML 5.4.1 and cython_sources

A requirements.txt pinned to PyYAML==5.4.1 fails before it even starts building, on Windows and Linux alike:

  Getting requirements to build wheel: finished with status 'error'
  error: subprocess-exited-with-error
      AttributeError: 'build_ext' object has no attribute 'cython_sources'
  note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed to build 'pyyaml' when getting requirements to build wheel

PyYAML 5.4.1 builds with Cython, and pip fetches the newest Cython for the build. Cython 3 removed what PyYAML 5.4.1’s setup.py relies on.

Move the pin to a version with wheels for your Python:

PyYAML==6.0.3

If you can’t leave 5.4.1, build it with an older Cython yourself:

pip install "cython<3" setuptools wheel
pip install --no-build-isolation pyyaml==5.4.1

On Windows without the build tools, that workaround got past cython_sources and then stopped at the Visual C++ error above. Moving to 6.0.3 avoided both. A pin to pyyaml==6.0.1 is cause 1: no wheel for 3.14, and the same new pin fixes it.

Docker slim images: no error, but no C part either

In the official python:3.15-slim image, which has no compiler, pip install pyyaml built PyYAML from source without printing a single error:

  Downloading pyyaml-6.0.3.tar.gz (130 kB)
  Building wheel for pyyaml (pyproject.toml): finished with status 'done'
Successfully installed pyyaml-6.0.3

On Linux, the missing compiler is the error PyYAML’s fallback catches, so it quietly installed the pure-Python build: yaml.__with_libyaml__ was False. The full python:3.15 image, which ships with a compiler, built the C part (True), and python:3.14-slim got a ready-made wheel with it (True).

So you can upgrade a slim image to Python 3.15 and only find out when something asks for CSafeLoader. If you need it, install PyYAML in a stage built on the full python:3.15 image, which built the C part in my run, or stay on a 3.14 image until PyYAML ships 3.15 wheels.

How this was tested

Windows 11 Pro without any C++ compiler, on October 12 and 13, 2026: Python 3.14.5 (64-bit), 3.14.8 (32-bit) and 3.15.0, from python.org through the Python install manager, each package in a fresh virtual environment. The Build Tools runs used GitHub Actions’ windows-latest with Python 3.14.7; the script and workflow are public. Every error above is the real output.

The PyYAML section was tested on October 30, 2026. Windows 11 Pro with no Visual C++ build tools: Python 3.15.2 from python.org’s official package (checksum checked), pip 26.2.2, and Python 3.14, each case in a fresh virtual environment. Linux on GitHub Actions ubuntu-latest, in clean python:3.15-slim, python:3.15 and python:3.14-slim images. The speed comparison loaded the same generated 944 KB YAML file with each loader once; the exact times varied with machine load, the ratio held. The scripts and the full output are public.

— N.K., end of entry No.064

Useful? Pass it on:Post on XFollow @EmotionalMatter

Related entries

  1. No.063

    Python 3.15 on Windows: which packages install (tested)

    Most of the stack is ready: numpy, pandas, scipy, scikit-learn, polars, pydantic, FastAPI, Django and the OpenAI and Anthropic SDKs all install on 3.15, and so do PyTorch (since torch 2.15.0) and sentencepiece (since 0.2.3). What fails on Windows: TensorFlow (no 3.15 builds at all), PyYAML and everything that needs it, such as transformers (no 3.15 wheel, so pip tries to compile it), jupyterlab, and langchain (Rust and C dependencies with no 3.15 wheels).

    TESTED10 minWindows
  2. No.094

    Python CERTIFICATE_VERIFY_FAILED, tested on 3.12 to 3.15

    certificate verify failed: unable to get local issuer certificate, or Basic Constraints of CA cert not marked critical on Python 3.13+. Each cause tested.

    > requests.exceptions.SSLError: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/

    FIXED3 minWindows
  3. No.075

    Python was not found, or pip not recognized (Windows fix)

    "Python was not found" comes from a Microsoft Store placeholder python.exe, not Python, and exits with 9009. How to see which python.exe wins, and the pip fix.

    > Python was not found; run without arguments to install from the Microsoft Store, or disable this shortcut from Settings > Apps > Advanced app settings > App execution aliases.

    FIXED3 minWindows
  4. No.074

    pip error: externally-managed-environment, tested on 8 systems

    Ubuntu 24.04+, Debian 12+ and Homebrew Python block pip install; Ubuntu 22.04, Fedora and Docker python images don't. Which fix to use: venv, uv, pipx or apt.

    > error: externally-managed-environment

    FIXED4 min

Post card · Every Sunday

What broke this week.

One email on Sundays: the Node, TypeScript, Python and AI SDK releases that broke builds that week, each one reproduced, with a link to the fix that worked. Never shared, and you can leave any time.

— Nilay

or follow by RSSor on X

By subscribing you agree to the privacy note. One click to leave.

tip: paste the exact error text