From 72f682c5136e12c87c8a81a80b56a63ee1e5e1e4 Mon Sep 17 00:00:00 2001 From: Benjamin Marshall <13389193+benm-dev@users.noreply.github.com> Date: Sun, 18 Jan 2026 22:03:34 +1100 Subject: [PATCH 1/5] Fix mirrored networking loopback endpoint creation failure ## Problem After installing KB5074109 (January 2026), WSL mirrored networking fails to create the loopback endpoint, causing localhost (127.0.0.1) TCP/UDP connections to fail. Users see the loopback0 interface in state DOWN with NO-CARRIER. ## Root Cause Analysis HNS loopback networks no longer accept firewall policies when creating endpoints. Direct HCN API testing confirms: - Test 1: Endpoint WITH firewall policy -> 0x803B001B (FAIL) Error: 'Invalid JSON document string. {{Policies.VmCreatorId,UnknownField}}' - Test 2: Endpoint with VirtualNetwork field -> 0x803B001B (FAIL) Error: 'Invalid JSON document string. {{VirtualNetwork,UnknownField}}' - Test 3: Endpoint with HostComputeNetwork only -> 0x00000000 (SUCCESS) The current code in MirroredNetworking::AddNetworkEndpoint() creates all endpoints with firewall policies when m_config.FirewallConfig.Enabled() is true (the default), causing loopback endpoint creation to fail silently. ## Solution - Add IsLoopback field to HNSNetwork struct to detect loopback networks - Skip firewall policies when creating endpoints on loopback networks - Use HostComputeNetwork instead of VirtualNetwork for loopback endpoints ## Testing Verified on Windows Build 26220.7535: 1. HCN API tests confirm endpoint creation succeeds without firewall policies 2. WSL localhost TCP connectivity works when loopback0 is properly configured Fixes #14080 Related: #14063 --- src/shared/inc/hns_schema.h | 3 ++- .../service/exe/MirroredNetworking.cpp | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/shared/inc/hns_schema.h b/src/shared/inc/hns_schema.h index 2d9f98aa47..a52b781cb3 100644 --- a/src/shared/inc/hns_schema.h +++ b/src/shared/inc/hns_schema.h @@ -415,8 +415,9 @@ struct HNSNetwork std::vector Subnets; NetworkFlags Flags{}; InterfaceConstraint InterfaceConstraint{}; + bool IsLoopback{}; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HNSNetwork, ID, Name, SourceMac, DNSSuffix, DNSServerList, DNSDomain, Subnets, Flags, InterfaceConstraint); + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HNSNetwork, ID, Name, SourceMac, DNSSuffix, DNSServerList, DNSDomain, Subnets, Flags, InterfaceConstraint, IsLoopback); }; enum class NetworkMode diff --git a/src/windows/service/exe/MirroredNetworking.cpp b/src/windows/service/exe/MirroredNetworking.cpp index 417006ea73..ea8f81bdbd 100644 --- a/src/windows/service/exe/MirroredNetworking.cpp +++ b/src/windows/service/exe/MirroredNetworking.cpp @@ -440,7 +440,20 @@ void MirroredNetworking::AddNetworkEndpoint(const GUID& NetworkId) noexcept endpointInfo.NetworkId = NetworkId; endpointInfo.EndpointId = endpointId; - if (m_config.FirewallConfig.Enabled()) + // Loopback networks don't support firewall policies - creating an endpoint with firewall + // policies on a loopback network will fail with HCN error 0x803B001B ("Invalid JSON document + // string"). This behavior changed in KB5074109. Additionally, loopback networks require + // HostComputeNetwork instead of VirtualNetwork in the endpoint settings. + // See: https://github.com/microsoft/WSL/issues/14080 + const bool isLoopbackNetwork = properties.IsLoopback; + if (isLoopbackNetwork) + { + WSL_LOG( + "MirroredNetworking::AddNetworkEndpoint [Loopback network - using simplified endpoint settings]", + TraceLoggingValue(NetworkId, "networkId")); + } + + if (m_config.FirewallConfig.Enabled() && !isLoopbackNetwork) { // Create HNS firewall policy object for the endpoint hns::HostComputeEndpoint hnsEndpoint{}; @@ -470,6 +483,15 @@ void MirroredNetworking::AddNetworkEndpoint(const GUID& NetworkId) noexcept hnsEndpoint.Policies.emplace_back(std::move(endpointFirewallPolicy)); endpointSettings = ToJsonW(hnsEndpoint); } + else if (isLoopbackNetwork) + { + // Loopback networks require HostComputeNetwork (not VirtualNetwork) and don't support policies + hns::HostComputeEndpoint hnsEndpoint{}; + hnsEndpoint.HostComputeNetwork = NetworkId; + hnsEndpoint.SchemaVersion.Major = 2; + hnsEndpoint.SchemaVersion.Minor = 16; + endpointSettings = ToJsonW(hnsEndpoint); + } else { // If Hyper-V Firewall is not supported for this scenario, only configure the basic HNS endpoint object From 95534f5543b313b5653246f887994c677866ee2b Mon Sep 17 00:00:00 2001 From: Benjamin Marshall <13389193+benm-dev@users.noreply.github.com> Date: Tue, 27 Jan 2026 16:12:10 +1100 Subject: [PATCH 2/5] update loopback network endpoint firewall policy check --- src/windows/service/exe/MirroredNetworking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/service/exe/MirroredNetworking.cpp b/src/windows/service/exe/MirroredNetworking.cpp index ea8f81bdbd..404e453055 100644 --- a/src/windows/service/exe/MirroredNetworking.cpp +++ b/src/windows/service/exe/MirroredNetworking.cpp @@ -483,7 +483,7 @@ void MirroredNetworking::AddNetworkEndpoint(const GUID& NetworkId) noexcept hnsEndpoint.Policies.emplace_back(std::move(endpointFirewallPolicy)); endpointSettings = ToJsonW(hnsEndpoint); } - else if (isLoopbackNetwork) + else if (m_config.FirewallConfig.Enabled() && isLoopbackNetwork) { // Loopback networks require HostComputeNetwork (not VirtualNetwork) and don't support policies hns::HostComputeEndpoint hnsEndpoint{}; From 1004388428034b32b6e52af1cec7d16d7374991a Mon Sep 17 00:00:00 2001 From: Benjamin Marshall <13389193+benm-dev@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:10:55 +1100 Subject: [PATCH 3/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../service/exe/MirroredNetworking.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/windows/service/exe/MirroredNetworking.cpp b/src/windows/service/exe/MirroredNetworking.cpp index 404e453055..d1da1471ea 100644 --- a/src/windows/service/exe/MirroredNetworking.cpp +++ b/src/windows/service/exe/MirroredNetworking.cpp @@ -453,7 +453,16 @@ void MirroredNetworking::AddNetworkEndpoint(const GUID& NetworkId) noexcept TraceLoggingValue(NetworkId, "networkId")); } - if (m_config.FirewallConfig.Enabled() && !isLoopbackNetwork) + if (isLoopbackNetwork) + { + // Loopback networks require HostComputeNetwork (not VirtualNetwork) and don't support policies + hns::HostComputeEndpoint hnsEndpoint{}; + hnsEndpoint.HostComputeNetwork = NetworkId; + hnsEndpoint.SchemaVersion.Major = 2; + hnsEndpoint.SchemaVersion.Minor = 16; + endpointSettings = ToJsonW(hnsEndpoint); + } + else if (m_config.FirewallConfig.Enabled()) { // Create HNS firewall policy object for the endpoint hns::HostComputeEndpoint hnsEndpoint{}; @@ -483,15 +492,6 @@ void MirroredNetworking::AddNetworkEndpoint(const GUID& NetworkId) noexcept hnsEndpoint.Policies.emplace_back(std::move(endpointFirewallPolicy)); endpointSettings = ToJsonW(hnsEndpoint); } - else if (m_config.FirewallConfig.Enabled() && isLoopbackNetwork) - { - // Loopback networks require HostComputeNetwork (not VirtualNetwork) and don't support policies - hns::HostComputeEndpoint hnsEndpoint{}; - hnsEndpoint.HostComputeNetwork = NetworkId; - hnsEndpoint.SchemaVersion.Major = 2; - hnsEndpoint.SchemaVersion.Minor = 16; - endpointSettings = ToJsonW(hnsEndpoint); - } else { // If Hyper-V Firewall is not supported for this scenario, only configure the basic HNS endpoint object From 9014f790595ae1708d3d24d3283b8a72a96977eb Mon Sep 17 00:00:00 2001 From: Benjamin Marshall <13389193+benm-dev@users.noreply.github.com> Date: Thu, 16 Apr 2026 06:19:49 +1000 Subject: [PATCH 4/5] Update src/windows/service/exe/MirroredNetworking.cpp Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/windows/service/exe/MirroredNetworking.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/windows/service/exe/MirroredNetworking.cpp b/src/windows/service/exe/MirroredNetworking.cpp index d1da1471ea..c01f1e18e2 100644 --- a/src/windows/service/exe/MirroredNetworking.cpp +++ b/src/windows/service/exe/MirroredNetworking.cpp @@ -446,15 +446,12 @@ void MirroredNetworking::AddNetworkEndpoint(const GUID& NetworkId) noexcept // HostComputeNetwork instead of VirtualNetwork in the endpoint settings. // See: https://github.com/microsoft/WSL/issues/14080 const bool isLoopbackNetwork = properties.IsLoopback; + if (isLoopbackNetwork) { WSL_LOG( "MirroredNetworking::AddNetworkEndpoint [Loopback network - using simplified endpoint settings]", TraceLoggingValue(NetworkId, "networkId")); - } - - if (isLoopbackNetwork) - { // Loopback networks require HostComputeNetwork (not VirtualNetwork) and don't support policies hns::HostComputeEndpoint hnsEndpoint{}; hnsEndpoint.HostComputeNetwork = NetworkId; From c02930c7916e982dad78a2a1936b05bfffe8700f Mon Sep 17 00:00:00 2001 From: Owen Jones Date: Tue, 23 Jun 2026 18:26:31 -0300 Subject: [PATCH 5/5] Fixed formatting issue preventing CI from passing --- src/shared/inc/hns_schema.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/inc/hns_schema.h b/src/shared/inc/hns_schema.h index a52b781cb3..c39fed9566 100644 --- a/src/shared/inc/hns_schema.h +++ b/src/shared/inc/hns_schema.h @@ -417,7 +417,8 @@ struct HNSNetwork InterfaceConstraint InterfaceConstraint{}; bool IsLoopback{}; - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(HNSNetwork, ID, Name, SourceMac, DNSSuffix, DNSServerList, DNSDomain, Subnets, Flags, InterfaceConstraint, IsLoopback); + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT( + HNSNetwork, ID, Name, SourceMac, DNSSuffix, DNSServerList, DNSDomain, Subnets, Flags, InterfaceConstraint, IsLoopback); }; enum class NetworkMode