Skip to content

Instantly share code, notes, and snippets.

@emilwojcik93
Last active September 3, 2025 21:29
Show Gist options
  • Save emilwojcik93/6f337453a482f15dde4959d0b032ae0e to your computer and use it in GitHub Desktop.
Save emilwojcik93/6f337453a482f15dde4959d0b032ae0e to your computer and use it in GitHub Desktop.
Automatically detects and fixes WSL Interop naming conflict (WSLInterop-late vs WSLInterop) in Ubuntu-family distributions. Version 2.0 with clean console output, wslpath integration, and reliable service installation.
<#
.SYNOPSIS
Automatically detects and fixes WSL Interop naming conflict issue (WSLInterop-late vs WSLInterop) in Ubuntu-family WSL distributions.
.DESCRIPTION
This script identifies the systemd-binfmt vs wslu naming conflict in WSL Ubuntu-family distributions (Ubuntu 24.04+)
and automatically installs a permanent systemd service fix. Only works with Ubuntu/Debian-based distributions that use apt and systemd.
Issue: https://github.com/microsoft/WSL/issues/13449
.PARAMETER Verbose
Enables detailed output during execution.
.EXAMPLE
# Run directly from GitHub Gist
&([ScriptBlock]::Create((irm https://gist.githubusercontent.com/emilwojcik93/6f337453a482f15dde4959d0b032ae0e/raw/Fix-WSLInterop.ps1))) -Verbose
.NOTES
Author: emilwojcik93
Version: 2.0 - Improved version with clean console output and reliable service installation
Requires: Windows 10/11 with WSL 2, Ubuntu-family distribution (Ubuntu/Debian with apt and systemd)
GitHub Issue: https://github.com/microsoft/WSL/issues/13449
This version uses file copy method and wslpath for reliable service creation.
Fixes console corruption issues from v1.0 by avoiding here-strings and complex escaping.
Improvements in v2.0:
- Uses wslpath for proper Windows-to-Unix path conversion
- Creates service file in Windows temp directory, copies to WSL
- Simple output functions prevent console corruption
- Reliable systemd service installation without escaping issues
- Silent apt installation to reduce output noise
Supported Distributions: Ubuntu 24.04+, Ubuntu derivatives, Debian with systemd
#>
[CmdletBinding()]
param()
$ErrorActionPreference = 'Continue'
$ProgressPreference = 'SilentlyContinue'
# Simple output functions without color to avoid console issues
function Write-Info { param($msg) Write-Output "[INFO] $msg" }
function Write-Success { param($msg) Write-Output "[SUCCESS] $msg" }
function Write-Warn { param($msg) Write-Warning "[WARNING] $msg" }
function Write-Err { param($msg) Write-Error "[ERROR] $msg" -ErrorAction Continue }
Write-Output "WSL Interop Issue Auto-Fix Script v2.0"
Write-Output "======================================"
Write-Output "GitHub Issue: https://github.com/microsoft/WSL/issues/13449"
Write-Output ""
# Check WSL installation
Write-Info "Checking WSL installation..."
$wslExe = Get-Command wsl.exe -ErrorAction SilentlyContinue
if (-not $wslExe) {
Write-Err "wsl.exe not found. Please install WSL first."
exit 1
}
# Check WSL distributions from registry
$lxssPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss"
if (-not (Test-Path $lxssPath)) {
Write-Err "No WSL distributions found. Please install Ubuntu."
Write-Output "Run: wsl --install -d Ubuntu"
exit 1
}
# Get default distribution
$distributions = Get-ChildItem -Path $lxssPath -ErrorAction SilentlyContinue
$defaultDistro = $null
$defaultGuid = Get-ItemProperty -Path $lxssPath -Name "DefaultDistribution" -ErrorAction SilentlyContinue
foreach ($distro in $distributions) {
$props = Get-ItemProperty -Path $distro.PSPath -ErrorAction SilentlyContinue
if ($props.DistributionName -and ($distro.PSChildName -eq $defaultGuid.DefaultDistribution)) {
$defaultDistro = $props.DistributionName
break
}
}
if (-not $defaultDistro) {
$firstDistro = Get-ItemProperty -Path $distributions[0].PSPath -ErrorAction SilentlyContinue
$defaultDistro = $firstDistro.DistributionName
}
Write-Success "Found WSL distribution: $defaultDistro"
# Check if it's Ubuntu-family
Write-Info "Verifying Ubuntu-family distribution..."
$ubuntuCheck = wsl -d $defaultDistro -u root -e bash -c "command -v apt && command -v systemctl" 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Err "Distribution '$defaultDistro' is not Ubuntu-family (missing apt or systemd)"
Write-Output "This script only works with Ubuntu/Debian-based distributions"
Write-Output ""
Write-Output "Alternative methods (work on any distribution):"
Write-Output "wsl bash -c `"powershell.exe -Command '\`$env:UserProfile' | tr -d '\r'`""
exit 1
}
Write-Success "Ubuntu-family distribution confirmed"
# Check for interop issue
Write-Info "Checking for WSL Interop issue..."
$wslInteropExists = wsl -d $defaultDistro -u root -e bash -c "test -f /proc/sys/fs/binfmt_misc/WSLInterop && echo 'true' || echo 'false'" 2>$null
$wslInteropLateExists = wsl -d $defaultDistro -u root -e bash -c "test -f /proc/sys/fs/binfmt_misc/WSLInterop-late && echo 'true' || echo 'false'" 2>$null
if ($wslInteropExists.Trim() -eq 'true') {
Write-Success "No WSL Interop issue detected - WSLInterop handler exists"
exit 0
}
if ($wslInteropLateExists.Trim() -ne 'true') {
Write-Success "No WSL Interop issue detected - systemd not using WSLInterop-late"
exit 0
}
Write-Warn "WSL Interop issue detected: WSLInterop-late exists but WSLInterop missing"
# Install wslu if needed
Write-Info "Checking wslu installation..."
$wsluInstalled = wsl -d $defaultDistro -u root -e bash -c "command -v wslvar && echo 'installed' || echo 'missing'" 2>$null
if ($wsluInstalled.Trim() -ne 'installed') {
Write-Info "Installing wslu package..."
wsl -d $defaultDistro -u root -e bash -c "DEBIAN_FRONTEND=noninteractive apt update -qq && apt install -y wslu -qq" >$null 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Success "wslu package installed"
} else {
Write-Warn "wslu installation may have failed"
}
}
# Create systemd service using file copy (avoids all escaping issues)
Write-Info "Creating permanent systemd service fix..."
# Create service file in Windows temp directory
$tempServiceFile = "$env:TEMP\wsl-interop-fix.service"
$serviceContent = @"
[Unit]
Description=Fix WSL Interop naming conflict for wslu utilities
After=systemd-binfmt.service
Wants=systemd-binfmt.service
[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo ":WSLInterop:M::MZ::/init:P" | tee /proc/sys/fs/binfmt_misc/register'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
"@
Set-Content -Path $tempServiceFile -Value $serviceContent -Encoding UTF8
# Copy service file to WSL using wslpath for proper path conversion
$unixPath = wsl -d $defaultDistro -e bash -c "wslpath '$tempServiceFile'" 2>$null
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($unixPath)) {
Write-Err "Failed to convert Windows path to Unix path"
exit 1
}
$result = wsl -d $defaultDistro -u root -e bash -c "cp '$($unixPath.Trim())' /etc/systemd/system/wsl-interop-fix.service" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Err "Failed to copy service file: $result"
Write-Output ""
Write-Output "Manual fix (temporary): wsl -u root -e bash -c `"echo ':WSLInterop:M::MZ::/init:P' | tee /proc/sys/fs/binfmt_misc/register`""
exit 1
}
# Clean up temp file
Remove-Item $tempServiceFile -Force -ErrorAction SilentlyContinue
# Reload, enable, and start service
Write-Info "Configuring systemd service..."
wsl -d $defaultDistro -u root -e bash -c "systemctl daemon-reload" >$null 2>&1
$enableResult = wsl -d $defaultDistro -u root -e bash -c "systemctl enable wsl-interop-fix.service" 2>&1
wsl -d $defaultDistro -u root -e bash -c "systemctl start wsl-interop-fix.service" >$null 2>&1
# Verify service is active
$serviceStatus = wsl -d $defaultDistro -u root -e bash -c "systemctl is-active wsl-interop-fix.service" 2>$null
if ($serviceStatus.Trim() -eq "active") {
Write-Success "WSL Interop fix service installed and running"
} else {
Write-Warn "Service created but may not be active (status: $serviceStatus)"
}
# Test the fix
Write-Info "Testing the fix..."
$finalTest = wsl -d $defaultDistro -u root -e bash -c "test -f /proc/sys/fs/binfmt_misc/WSLInterop && echo 'fixed' || echo 'still-broken'" 2>$null
if ($finalTest.Trim() -eq 'fixed') {
Write-Success "WSL Interop fix verified - WSLInterop handler now exists"
# Test wslu if available
$wsluTest = wsl -d $defaultDistro -e bash -c "wslvar UserProfile 2>&1" 2>$null
if ($wsluTest -notmatch "WSL Interopability is disabled") {
Write-Success "wslu utilities now work without errors"
}
} else {
Write-Warn "Fix may not have applied correctly"
}
Write-Output ""
Write-Output "Fix complete! The solution persists across WSL restarts."
Write-Output ""
Write-Output "Alternative methods (no system modifications needed):"
Write-Output "wsl bash -c `"powershell.exe -Command '\`$env:UserProfile' | tr -d '\r'`""
Write-Output "wsl bash -c `"cmd.exe /c 'echo %USERPROFILE%' | tr -d '\r'`""
@emilwojcik93
Copy link
Author

emilwojcik93 commented Sep 3, 2025

How to Use This Script v2.0

This script automatically fixes the WSL Interop naming conflict that causes false "interoperability disabled" errors in wslu utilities on Ubuntu-family distributions. Version 2.0 features improved console output and reliable service installation.

Quick Start (One Command)

Run directly from this gist (recommended):

&([ScriptBlock]::Create((irm https://gist.githubusercontent.com/emilwojcik93/6f337453a482f15dde4959d0b032ae0e/raw/Fix-WSLInterop.ps1))) -Verbose

Alternative Usage Methods

Download and run locally:

# Download the script
Invoke-WebRequest -Uri "https://gist.githubusercontent.com/emilwojcik93/6f337453a482f15dde4959d0b032ae0e/raw/Fix-WSLInterop.ps1" -OutFile "Fix-WSLInterop.ps1"

# Run with verbose output  
.\Fix-WSLInterop.ps1 -Verbose

# Run silently
.\Fix-WSLInterop.ps1

What This Script Fixes

Problem: Ubuntu 24.04+ with systemd enabled creates WSLInterop-late but wslu utilities expect WSLInterop, causing false error messages.

Before Fix:

$ wslvar UserProfile
grep: /proc/sys/fs/binfmt_misc/WSLInterop: No such file or directory
WSL Interopability is disabled. Please enable it before using WSL.
C:\Users\username

After Fix:

$ wslvar UserProfile
C:\Users\username

Requirements

  • Windows 10/11 with WSL 2
  • Ubuntu-family distribution (Ubuntu 24.04+, Debian with systemd)
  • No Windows admin privileges required
  • Not for other distributions (Alpine, CentOS, openSUSE, etc.)

What the Script Does (v2.0 Improvements)

  1. Detects WSL via Windows registry (reliable, no command parsing)
  2. Validates Ubuntu-family distribution (checks for apt and systemd)
  3. Identifies the issue by checking /proc/sys/fs/binfmt_misc/ files
  4. Installs wslu if needed (silent, non-interactive apt)
  5. Creates service file in Windows temp directory (clean creation)
  6. Uses wslpath for proper Windows-to-Unix path conversion
  7. Copies service to WSL via file system (avoids escaping issues)
  8. Installs systemd service with reliable systemctl commands
  9. Verifies fix works and persists across WSL restarts

v2.0 fixes console corruption issues from the original version.

Alternative Methods (Any Distribution)

If you have non-Ubuntu distributions or prefer not to modify systemd:

# PowerShell method (universal)
wsl bash -c "powershell.exe -Command '\$env:UserProfile' | tr -d '\r'"
wsl bash -c "powershell.exe -Command '\$env:UserName' | tr -d '\r'"

# CMD method (universal)
wsl bash -c "cmd.exe /c 'echo %USERPROFILE%' | tr -d '\r'"
wsl bash -c "cmd.exe /c 'echo %USERNAME%' | tr -d '\r'"

Troubleshooting

If the script fails:

# Manual temporary fix
wsl -u root -e bash -c "echo ':WSLInterop:M::MZ::/init:P' | tee /proc/sys/fs/binfmt_misc/register"

# Check systemd service status
wsl -u root -e bash -c "systemctl status wsl-interop-fix.service"

Console output issues in v1.0: If you experience corrupted console output, use the v2.0 simplified version that fixes these issues.

For non-Ubuntu distributions: Use the PowerShell/CMD alternative methods shown above.

Related Information

  • GitHub Issue: microsoft/WSL#13449
  • Affects: All Ubuntu 24.04+ WSL installations with systemd
  • Root Cause: systemd-binfmt vs wslu naming conflict
  • Solution: Permanent systemd service that creates both handlers

This script has been thoroughly tested and provides a permanent solution that survives WSL restarts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment