Skip to content
WSLHow-To Published Updated 4 min readViews unavailable

Running a Custom WSL 2 Kernel Without Losing the Supported Rollback Path

Building or selecting a compatible WSL 2 kernel, configuring .wslconfig correctly, and keeping a working path back to Microsoft's default kernel.

WSL 2 ships with a Microsoft-maintained Linux kernel, built from source Microsoft publishes at microsoft/WSL2-Linux-Kernel on GitHub. Most users never need anything else, but a specific kernel module, a feature only present in a newer or differently-configured kernel, or a driver you need to test can require building and loading your own — and doing that without losing the ability to get back to a known-working state is the part worth being deliberate about.

Why you’d want a custom kernel at all

The default WSL 2 kernel is built with a configuration Microsoft chose to balance broad compatibility, size, and boot speed for the general WSL user base — it doesn’t enable every kernel module or feature a specialized workload might need. Common reasons to build a custom kernel include enabling a specific filesystem or networking module the stock configuration excludes, testing against a newer kernel version than what’s currently shipped, or working with hardware-adjacent features (via USB/IP passthrough, for instance) that benefit from a specific kernel configuration.

Starting from Microsoft’s own source, not a blank configuration

Rather than configuring a kernel from scratch, clone Microsoft’s own WSL2 kernel source and branch, which already contains the WSL-specific patches and the baseline configuration the stock kernel is built from:

git clone https://github.com/microsoft/WSL2-Linux-Kernel.git --depth=1 -b linux-msft-wsl-6.6.y

Starting here and changing only the specific options you actually need keeps your custom build close to what Microsoft tests and ships, rather than introducing a large number of unrelated configuration differences that make troubleshooting a later problem considerably harder.

Installing build dependencies and configuring

sudo apt update
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses5-dev
cp Microsoft/config-wsl .config
make menuconfig

make menuconfig opens an interactive configuration editor — enable only the specific option you set out to change, then save and exit, rather than exploring broadly and toggling options you don’t have a specific reason to change.

Building the kernel and its modules

make -j$(nproc)
make INSTALL_MOD_PATH="$PWD/modules" modules_install

Building with -j$(nproc) parallelizes compilation across available CPU cores, which matters for a full kernel build’s otherwise lengthy compile time. If your target feature is built as a loadable module rather than compiled directly into the kernel, confirm the module actually built and is present under the specified module install path before proceeding — a successful kernel compile doesn’t guarantee a specific module was included if its dependencies or configuration prerequisites weren’t correctly enabled.

Pointing WSL at your custom kernel

Copy the resulting kernel image to a location Windows can reference, then point .wslconfig at it:

# %UserProfile%\.wslconfig
[wsl2]
kernel=C:\\Users\\YourName\\.wsl-kernels\\bzImage

The path must be an absolute Windows path using the .wslconfig file’s own escaping conventions, and this setting is global to the shared WSL 2 VM — it affects every distribution using that VM, not just one.

Applying the change and testing on a non-critical distribution first

wsl --shutdown

Restart WSL and launch a distribution you can afford to have misbehave temporarily, not your primary daily-driver environment. Verify the custom kernel actually loaded and that the specific feature you built it for is present:

uname -r
uname -a
lsmod | grep <your_module>

Beyond confirming the kernel version string matches your build, exercise the broader set of things WSL depends on working correctly — basic networking, filesystem access, and, if relevant to your setup, systemd and Docker — since a custom kernel missing an option the stock configuration included by default can silently break functionality unrelated to whatever you were specifically trying to add.

Recovering if the custom kernel doesn’t boot or breaks something

If a distribution fails to start, or starts but exhibits broken behavior, the direct rollback is removing or commenting out the kernel= line in .wslconfig and shutting down and restarting WSL again:

# kernel=C:\\Users\\YourName\\.wsl-kernels\\bzImage
wsl --shutdown

This returns WSL to Microsoft’s default, maintained kernel on the next start, with no other changes needed — keeping this rollback path fast and simple is exactly why testing on a non-critical distribution first, and never overwriting your only working .wslconfig without a saved copy of the previous version, matters.

Understanding what you’re taking on

Once you’re running a custom kernel, you’ve taken on responsibility for its updates and security patching yourself — Microsoft’s own kernel updates, delivered through the regular WSL update channel, no longer apply automatically to a kernel you’ve pointed .wslconfig at manually. Revisit and rebuild periodically against Microsoft’s updated kernel branches rather than freezing indefinitely on whatever version you originally built, particularly for any kernel-level security fix that lands upstream after your custom build was made.

Related:

Sources:

Comments