The dominant WSL problem is working on /mnt/c, which makes every file read cross a translation layer between Windows and Linux filesystem semantics. Clone into the Linux filesystem under /home instead. The second is that the same penalty makes search return fewer matches than expected while claude doctor still reports Search as OK. The rest are browser login that cannot complete, WSL1 refusing the native binary with an exec format error, WSL picking up the Windows Node installation, and CRLF line endings.
- Never work on
/mnt/c. This is most of the "WSL is slow" reports. - Search on
/mnt/creturns fewer matches, andclaude doctorstill says OK. - Browser login may not return. Paste the login code, or set
BROWSER. Exec format errormeans WSL1. Convert the distribution to WSL2.exec: node: not foundmeans WSL is using the Windows Node.- Set
core.autocrlf inputor scripts fail on a stray\r.
The filesystem trap
cd /mnt/c/Users/you/projects/app
claude
mkdir -p ~/projects && cd ~/projects
git clone git@github.com:you/app.git
cd app
claude
Relative cost of the same operations across the boundary.
| Operation | Linux filesystem | /mnt/c |
|---|---|---|
| Read one file | Fast | Noticeably slower |
| Search the repository | Fast | Much slower, and less complete |
| Run the test suite | Normal | Substantially slower |
| An agent session end to end | Normal | Frustrating |
If the project genuinely has to live on C:, that is a real constraint and the answer is not WSL. Run Claude Code natively on Windows instead, where the same files are local.
Searches that quietly miss files
This one is worse than slowness because it changes the answers rather than the wait. Anthropic documents it directly: the disk read penalty from working across file systems on WSL can cause search to return fewer matches than expected. Search still works. It just does not find everything.
- Move the project to the Linux filesystem. The only fix that removes the cause.
- Narrow the search. "Find JWT validation in the auth-service package" searches far fewer files than "find the auth code".
- Name the file when you know it. A direct read never depends on the search returning complete results.
- Or go native. Windows-native Claude Code reads
C:at full speed.
Login that never returns
WSL2 runs in its own network namespace, so the browser opens on Windows and its redirect cannot reach the callback server inside WSL. The flow starts and never completes. As of August 2026 this is expected behaviour, and the login screen accounts for it.
- Paste the code. After you sign in, the browser shows a login code instead of redirecting. Paste it into the terminal at the
Paste code here if promptedprompt. - Copy the URL if the browser never opens. Press
cat the login prompt to copy the OAuth URL, then open it in a Windows browser. - Point WSL at a Windows browser. Set
BROWSERto the executable path. - Use the stdin path if pasting does nothing.
claude auth loginreads the pasted code from standard input, which works when the terminal paste binding does not reach the interactive field.
export BROWSER="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
claude
# or, when pasting into the interactive prompt does nothing
claude auth login
WSL1, and the Windows Node problem
Two failures that look like broken installs and are neither. The first is a known WSL1 incompatibility with the native binary.
cannot execute binary file: Exec format error
wsl --set-version <DistroName> 2
# add to ~/.bashrc inside WSL
claude() {
/lib64/ld-linux-x86-64.so.2 "$(readlink -f "$HOME/.local/bin/claude")" "$@"
}
source ~/.bashrc
The second only applies if you installed through npm inside WSL. WSL imports the Windows PATH by default, so it can pick up the Windows Node and npm without telling you.
which node # /usr/bin/node good
which npm # /mnt/c/Program Files/nodejs/npm this is the problem
# platform mismatch during install
npm config set os linux
npm install -g @anthropic-ai/claude-code --force # never with sudo
# nvm not loaded in this shell is the usual root cause
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# still losing to Windows nvm? put the Linux Node first explicitly
export PATH="$HOME/.nvm/versions/node/$(node -v)/bin:$PATH"
Line endings, memory, and credentials
git config --global core.autocrlf input
# fix a file that already has them
sed -i 's/\r$//' script.sh
The remaining WSL-specific failures.
| Symptom | Cause | Fix |
|---|---|---|
bad interpreter: ^M | CRLF line endings | core.autocrlf input |
| Works in terminal, not in VS Code | PATH set in an interactive-only file | Move the export to ~/.profile |
EACCES on npm install | Global prefix not writable | User prefix, or the native installer. Never sudo. |
| Very high memory use | The WSL2 virtual machine grows | Set limits in .wslconfig on the Windows side |
| Git asks for credentials repeatedly | No credential helper | Use the Windows Git credential manager |
| Sandbox unavailable | bubblewrap and socat missing | sudo apt-get install bubblewrap socat, then restart |
[wsl2]
memory=8GB
processors=4
When to go native instead
| Your project lives | Use |
|---|---|
| In the Linux filesystem | WSL2 |
On C:, and stays there | Native Windows |
On C:, and you can move it | Move it, then WSL2 |
| Linux toolchain, Docker, make | WSL2 |
| Visual Studio or .NET on Windows | Native |
| You want the OS sandbox | WSL2 |
Questions people ask
Almost certainly because the project is on /mnt/c. Every file read crosses a translation layer between Windows and Linux filesystem semantics, and an agent reads constantly. Clone into the Linux filesystem under /home instead.
The same cross-filesystem read penalty means search can return fewer matches than expected on /mnt/c. claude doctor still reports Search as OK, because ripgrep itself is fine. Move the project to the Linux filesystem, or make searches more specific so fewer files are involved.
Whichever side your code lives on. WSL2 for projects in the Linux filesystem or a Linux toolchain, native Windows for projects that stay on C:. Mixing the two is the only genuinely bad choice. WSL2 is also required if you want the OS-level Bash sandbox, which native Windows does not support.
The browser opens on Windows and its redirect cannot reach the callback server inside WSL2. Sign in, then paste the login code the browser shows into the terminal prompt. If the browser never opens, press c to copy the URL, or set BROWSER to a Windows browser path. If pasting does nothing, run claude auth login, which reads the code from standard input.
You are on WSL1, whose loader cannot handle the native binary program headers. Convert the distribution with wsl --set-version <DistroName> 2 from PowerShell. If you have to stay on WSL1, wrap the binary in a shell function that invokes it through /lib64/ld-linux-x86-64.so.2.
Your WSL environment is using the Windows Node installation. Run which node and which npm: paths starting with /mnt/c are Windows binaries. Install Node through your distribution package manager or nvm, make sure nvm is loaded in ~/.bashrc, and do not disable Windows PATH importing to work around it.
CRLF line endings from Windows. Set git config --global core.autocrlf input so future checkouts use LF, and fix existing files with sed -i 's/\r$//' script.sh.
Create .wslconfig in your Windows user directory and set memory and processor limits for the WSL2 virtual machine, then restart WSL. Inside the session, /compact and clearing between tasks reduce what Claude Code itself holds.
Sources
Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.