Error

"linker link.exe not found" — How to Fix on Windows

Fix Rust's 'linker link.exe not found' error on Windows by installing the Visual Studio Build Tools with the Desktop development with C++ workload, then opening a fresh terminal.

You installed Rust on Windows and the build failed

You just finished installing Rust on Windows. You followed the tutorial, typed cargo new hello, and hit cargo run. Instead of "Hello, world!", your terminal spits out a wall of text screaming about link.exe not being found. This is the rite of passage for every Rustacean on Windows. The compiler did its job. It turned your code into machine instructions. But it can't finish the job because it's missing the tool that glues everything together.

The error message is actually quite helpful once you know what to look for. It tells you that rustc compiled your code successfully, generated object files, and then tried to call a program named link.exe to produce the final executable. The operating system replied that link.exe does not exist. On Linux and macOS, the linker comes from the system C toolchain that is usually already installed. On Windows, the linker lives inside Microsoft's Visual Studio toolchain, and you have to install it separately.

Why Rust needs a linker

Rust's compiler, rustc, is a translator. It takes your high-level Rust code and converts it into object files. An object file is a chunk of machine code, but it is incomplete. It contains references to functions in the standard library, to external crates, and to the operating system's startup routines. None of those references are resolved yet. The object file says "call the println function" but doesn't know the memory address where println lives.

The linker steps in to resolve those references. It finds the actual addresses of every function call, merges all the object files, pulls in the standard library, and produces a single executable file that the OS can run. On Windows, the default linker is link.exe, which is part of Microsoft's MSVC toolchain.

Rust does not ship with link.exe because Microsoft licenses it separately. The linker is bundled with Visual Studio and the Build Tools. Rust relies on the host system to provide it. This separation keeps the Rust installer small and avoids redistributing Microsoft's proprietary tools.

Windows supports two Rust toolchains. The default and recommended one is MSVC. It uses Microsoft's linker and produces binaries that integrate cleanly with Windows debugging tools and other Windows programs. There is also a GNU toolchain that uses MinGW's linker. The GNU toolchain has different conventions and can cause compatibility issues with some crates. Unless you have a specific reason to use GNU, stick with MSVC.

The error message

Here is the exact error you see when the linker is missing. The compiler stops at the linking stage and reports the failure.

# This is the terminal output when the linker is missing.
# The compiler compiled the code but failed to find link.exe.
error: linker `link.exe` not found
  |
  = note: program not found

note: the msvc targets depend on the msvc linker but `link.exe` was not found

note: please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio
      were installed with the Visual C++ option.

The note at the bottom gives the solution directly. You need Visual Studio or the Build Tools, and you must install the Visual C++ option. The "Visual C++ option" is the key phrase. It ensures the linker and the necessary headers are present.

Install the Build Tools

You do not need the full Visual Studio IDE. The full IDE is massive and includes features you will never use for Rust. You need the free Build Tools package. It is a slimmed-down installer that includes the linker, the Windows SDK, and the C++ headers Rust occasionally pulls in.

Rust's standard library uses C++ headers internally to interface with Windows APIs. Even if your code is pure Rust, the compiler needs those headers to link against the system. The Build Tools provide them.

The fastest way to get the tools is using winget, the package manager built into Windows 10 and 11. Open PowerShell or Command Prompt and run the install command.

# Installs the Visual Studio 2022 Build Tools.
# This pulls in link.exe, the Windows SDK, and C++ headers.
winget install Microsoft.VisualStudio.2022.BuildTools

If winget is not available, download the installer from the Visual Studio downloads page. Look for "Build Tools for Visual Studio" rather than the full IDE. During the install, you will see a list of workloads. Check the box for Desktop development with C++. That single checkbox pulls in the linker, the Windows SDK, and the C++ runtime headers. Do not worry about the other workloads. They are irrelevant for Rust and just waste disk space.

After the installer finishes, close any open terminals and reopen them. The Build Tools setup updates environment variables, and existing shell sessions do not pick those changes up. This trips people up surprisingly often. The shell reads the PATH once when it starts. If the PATH changes while the shell is running, the shell keeps using the old PATH.

Restart the shell. Environment variables do not teleport into existing processes.

Verify the fix

Once the Build Tools are in place, verify that the linker is visible and build a project to confirm the pipeline works. The where command shows the path to an executable on your PATH. If it returns a path, the linker is found.

# Check that the linker is now on your PATH.
# This should return a path like C:\Program Files\Microsoft Visual Studio\...
where link.exe

# Build a fresh project to test the full pipeline.
# Cargo compiles the code and invokes link.exe to create the binary.
cargo new test-linker
cd test-linker
cargo build

If everything is wired up, cargo build will print "Finished" and produce a binary in the target/debug directory. The build succeeded, the linker produced a real .exe, and the environment is ready.

If you see "Finished", the linker is working. Your environment is ready.

Debugging persistent errors

If cargo build still fails with the linker error after a fresh terminal, your PATH is not configured correctly. The Build Tools come with a "Developer Command Prompt for VS 2022" shortcut in the Start menu. This shortcut runs a script that sets up all the environment variables for the session. It bypasses the system PATH and configures the shell directly.

Try running cargo build from the Developer Command Prompt. If it works there, your system PATH is missing the Build Tools directories. You can either use the Developer Command Prompt for all builds, or add the Build Tools bin directory to your system PATH manually.

When the error persists, you need to see what cargo is trying to do. Run cargo build -v. This prints the exact command line rustc passes to the linker. Look for the line starting with link.exe. If the path looks wrong, your environment is misconfigured. If the command includes flags you do not recognize, a crate is injecting custom linker arguments.

# Run cargo with verbose output to see the exact linker command.
# Look for the line invoking link.exe to check paths and flags.
cargo build -v

The verbose output shows every step of the build. It reveals which compiler is running, which target is selected, and exactly how the linker is invoked. This information is essential when the standard error message is not enough.

Trust the verbose output. It shows exactly what the compiler is trying to do.

Common pitfalls

Several scenarios cause this error even when the tools are installed.

You have Visual Studio Community installed but never checked the C++ workload. The default installation often skips C++ to save space. Open the Visual Studio Installer, click Modify next to your install, and look at the workloads tab. If "Desktop development with C++" is unchecked, check it and let it install.

You have multiple versions of Visual Studio installed. The PATH might point to an older version that is missing the linker, or the versions might conflict. The Developer Command Prompt handles multiple versions correctly by selecting the right one based on the shortcut. Use the prompt to avoid version conflicts.

You are on a corporate machine where Group Policy strips the Build Tools PATH entries on logout. Corporate environments often reset environment variables to a known state. The Developer Command Prompt works around this by setting variables for the session. Talk to your IT department if you need a permanent fix, or rely on the prompt.

You accidentally switched to the GNU toolchain. Rust on Windows supports both MSVC and GNU targets. If you ran rustup default stable-x86_64-pc-windows-gnu, the compiler will look for x86_64-w64-mingw32-gcc instead of link.exe. Check your active target with rustup show. If it ends in -gnu, switch back to MSVC.

# Switch back to the MSVC toolchain if you accidentally selected GNU.
# This ensures rustc looks for link.exe instead of the MinGW linker.
rustup default stable-x86_64-pc-windows-msvc

Treat the Developer Command Prompt as your escape hatch. If the build fails, run it from there to isolate PATH issues.

Decision: MSVC vs GNU vs Workarounds

Use the MSVC toolchain when you want the standard Windows experience. Most crates, tutorials, and debugging tools assume MSVC. It produces binaries that integrate perfectly with Windows and avoids compatibility walls.

Use the GNU toolchain when you need a smaller footprint or are porting code from Linux that relies on GCC-specific features. The GNU toolchain uses MinGW and avoids Microsoft's installer, but you will hit compatibility issues with some Windows-specific crates and debugging integration is rougher.

Use the Developer Command Prompt when your system PATH is corrupted or managed by group policy. The prompt configures the environment variables correctly for the session, letting you build without fixing the global PATH.

Reach for rustup target add when you need to cross-compile or test both toolchains. You can install multiple targets and switch between them without reinstalling Rust. This is useful for verifying that your code works on both MSVC and GNU.

Where to go next