Support for miscellaneous binary formats (binfmt_misc) with Ubuntu on WSL¶
A key feature of WSL is binary interoperability, which allows
Windows binaries to be run inside WSL and vice-versa. Linux can run Windows binaries thanks to binfmt_misc, a
capability offered by the Linux kernel. With binfmt_misc, arbitrary executable file formats can be recognised and
passed to certain user space applications, such as interpreters, emulators and virtual machines, which can then
execute that specific format. The executable formats are registered via a file interface, usually located at
/proc/sys/fs/binfmt_misc/register or using wrappers such as those offered by binfmt-support or
systemd-binfmt.service. WSL registers Windows binaries to be passed to the /init program, which knows how
to pass that along to Windows (check /proc/sys/fs/binfmt_misc/WSLInterop* in a WSL distro instance).
Historically, the systemd unit systemd-binfmt.service was known to break WSL binary
interoperability, so it was disabled for Ubuntu on WSL. This documentation explains these issues
with WSL binary interoperability, why they no longer apply in more recent versions of Ubuntu and
WSL, and what you can do if you still have problems.
The systemd-binfmt.service and Windows binary interoperability¶
With systemd enabled, systemd-binfmt.service runs during boot, reads configuration files from specific
directories and registers additional executable formats with the kernel. All registrations are removed when
the service stops. If that service is not aware of the WSL registration mechanism, Windows binary
interoperability can break due to different factors, including:
binfmt_miscmount point being shared by multiple distro instances cause interoperability to be broken for multiple instances when one is shutdown. Since the WSL distro instances are effectively containers sharing the same kernel, when a distro instance stops andsystemd-binfmt.servicequits, it can break the registration for other instances.Startup ordering. If WSL didn’t order its own registration after that service, the service would break WSL interoperability at boot time.
Service restart. Restarting
systemd-binfmt.serviceimplies unregistering and re-registering executable file formats. That can easily happen without the user being aware, such as when installing emulators or other packages that rely onbinfmt_misc.
WSL protection of binfmt registrations¶
The scenarios above were reported by users in previous versions of WSL. The developers have since
implemented numerous improvements. From version 2.5.7, WSL is capable of restoring its binfmt
registration at startup and when that service is restarted. This is achieved by implementing a
systemd generator that creates an override for the systemd-binfmt.service unit. Generators are
small executables that systemd runs when it loads the system configuration, either automatically at
system startup or manually (due systemctl daemon-reload), generally used to create or override
systemd units. The override created by the WSL generator stays in sync with systemd-binfmt.service
and recreates the WSL binfmt registration if needed. That strategy is more reliable than previous
mechanisms implemented by WSL to protect the binfmt registration. Therefore, Ubuntu 24.04 LTS and
later no longer comes with that unit disabled, as we no longer consider it a potential issue for
Ubuntu users on WSL.
In the unlikely event that WSL instances still have binary interoperability issues, which could be
caused by systemd-binfmt.service or another systemd unit changing the binfmt registrations, an
easy solution is to override the unit to disable it under WSL. To override the unit, run the command
systemctl edit <UNIT_NAME> and entering the following contents:
[Unit]
ConditionVirtualization=!wsl
And then run the command:
$ sudo systemctl daemon-reload
That creates a file at /etc/systemd/system/<UNIT_NAME>/override.conf with the contents above,
effectively disabling that unit under WSL.
If later you need to re-enable the unit, remove that file and run sudo systemctl daemon-reload.