HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Windows 11 Windows 11Network Location AwarenessWindows FirewallGroup PolicyIntuneActive DirectoryTroubleshootingPowerShell

The firewall flipped to Public and broke everything: Network Location Awareness and the domain-detection race

IA
Imran Awan
21 August 2026

A laptop boots on the corporate LAN. The user signs in. The line-of-business app cannot reach its server. The file share times out. The printer is gone. Nothing on the device changed overnight, and nothing on the network changed either.

You open Windows Defender Firewall and the answer is sitting there in plain sight. The network is classified Public. Every firewall rule your team scoped to the Domain profile is inert, because as far as Windows is concerned this machine is sitting in an airport lounge.

This is not a firewall bug. It is a classification outcome. Windows decides what kind of network you are on before it decides which firewall rules apply, and that decision is a race. This post is about that race: what makes the decision, what "Domain" actually costs to earn, where the evidence lives, and which mitigations Microsoft actually supports.

The short version

Being domain-joined does not earn you the Domain firewall profile. Windows only grants the DomainAuthenticated category after it resolves a domain controller through a DNS SRV lookup and completes an LDAP bind on TCP port 389. If the network adapter comes up before that succeeds, the network is classified Public, the Public firewall profile applies, and Domain-scoped rules do not. It usually self-corrects within seconds, but negative caching, VPN route timing and fast startup can make it stick. The supported mitigations are to shrink the window with the wait-for-network and Group Policy wait-time settings, to stop relying on DC reachability by configuring TLS-based network authentication through the NetworkListManager CSP, and to set a safe location type for unidentified networks.

The problem: the Domain profile silently is not there

Windows Firewall has three profiles: Domain, Private and Public. A profile is just a named bucket of settings and rules. Windows picks the bucket based on how it classified the network the traffic is going over.

Microsoft states the rule plainly in the Windows Firewall overview: "The domain network profile is automatically applied to a device that is joined to an Active Directory domain, when it detects the availability of a domain controller. This network profile cannot be set manually."

Read that second sentence again. There is no switch, no checkbox and no registry value that says "this is the corporate network, trust me". Domain is a status the device has to earn, every time, on every network change. When it fails to earn it, Microsoft's own support guidance lists exactly the symptoms you are seeing.

The reason this is so hard to catch is that it is usually transient. The device classifies Public, then a few seconds later corrects itself to DomainAuthenticated. By the time the user calls the helpdesk and you remote in, the machine looks fine. Here is what that correction looks like in the event log on a real domain-joined Windows 11 device.

Event Viewer - Microsoft-Windows-NetworkProfile/Operational
20:10:44  10000  Network Connected  Name: Identifying...  Type: Unmanaged  State: Connected  Category: Public
20:10:58  10000  Network Connected  Name: contoso.com  Type: Managed  State: Connected,IPV4 (Internet)  Category: Public
20:11:02  10002  Network Category Changed  Name: contoso.com  Type: Managed  Category: Domain Authenticated
Illustrative, built from a genuine run with the network name replaced. Note the eighteen seconds in which the device was connected, working, and classified Public.

Eighteen seconds does not sound like much. It is plenty. A logon script, a mapped drive, a management agent check-in and an app that opens a socket at startup all happen inside that window. They fail, the user sees the failure, and the evidence evaporates before you look.

Context, in plain English. This post is about classification: how Windows decides a network is Domain, Private or Public. It is not about which rule wins when several match, or how local rules merge with policy rules inside a profile. Those are separate mechanics with their own failure modes. Here the rules are fine. They are simply attached to a profile that is not currently active.

Why it happens: Domain is earned by an LDAP bind

Two components share this job, and it helps to keep them apart.

NCSI is the Network Connectivity Status Indicator. It answers "is there internet, and is it real internet or local-only?" using an HTTP request to a probe endpoint (the "active probe") plus passive inspection of inbound packets (the "passive probe"). NCSI is why you get the globe with no internet icon.

NLA is Network Location Awareness. Microsoft describes the NLA service provider as the thing that "enables Windows Sockets 2 applications to identify the logical network to which a Windows computer is attached". The part that matters to you is that it performs the domain authentication step that decides whether a network is Domain.

Here is the chain, in order, from a network event to a firewall profile.

  1. Something changes on the network stack. Microsoft lists the triggers: an IP route is added or removed, an IP address is added or removed, an adapter disconnects or reconnects, an adapter is disabled or re-enabled, a DHCP event occurs (lease renewal, DNS server added or removed), or an NCSI setting changes.
  2. That change triggers NCSI detection, which works out the connectivity level.
  3. In parallel, domain detection starts. The service calls the DsGetDcName function to retrieve a DC name. Under the covers that is a DNS SRV lookup for a name of the form _ldap._tcp.<SiteName>._sites.dc._msdcs.<DomainName>.
  4. If DNS returns a DC, the machine opens a TCP connection to that DC on port 389.
  5. Inside that connection it sends an LDAP bind request. Only when the bind succeeds does the machine "identify itself in the domain network".
  6. The resulting category is written to the network profile, and Windows Firewall applies the matching profile.

Every one of those six steps can be slow or fail while the adapter is otherwise perfectly up. That is the entire story of this bug.

The three categories, and their numbers

Windows exposes the category through the Network List Manager API as the NLM_NETWORK_CATEGORY enumeration. These are the documented values, and they are the same numbers you will see in the registry later.

ConstantValueMeaning (Microsoft wording)
NLM_NETWORK_CATEGORY_PUBLIC0The network is a public (untrusted) network.
NLM_NETWORK_CATEGORY_PRIVATE0x1The network is a private (trusted) network.
NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED0x2The network is authenticated against an Active Directory domain.

There is a companion enumeration, NLM_DOMAIN_TYPE, and it is the one that explains the middle state everybody trips over.

ConstantValueMeaning (Microsoft wording)
NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK0The Network is not an Active Directory Network.
NLM_DOMAIN_TYPE_DOMAIN_NETWORK0x1The Network is an Active Directory Network, but this machine is not authenticated against it.
NLM_DOMAIN_TYPE_DOMAIN_AUTHENTICATED0x2The Network is an Active Directory Network, and this machine is authenticated against it.

Value 1 is the flap made visible. Windows can see that this is an Active Directory network and still refuse to treat it as one, because the bind has not succeeded. In the network adapter properties this shows up as the network name followed by "(Unauthenticated)".

Gotcha: you cannot set Domain by hand. Set-NetConnectionProfile switches a category between Private and Public only. Microsoft's own tip in the firewall documentation says exactly that. Any script, runbook or remediation that claims to "force the Domain profile" is either wrong or is doing something unsupported. If a network is stuck Public, the fix is to make domain detection succeed, not to overwrite the category.

What changed in Windows 11

If you learned this feature on Windows 7 or Windows 10, one thing has moved. Microsoft's support article states it directly: "Starting from Windows 11, the NLA service is no longer responsible for detecting the domain profile. Instead, the Network List Manager does this job." The NCSI documentation says the same thing from the other side: "As of Windows 11, NCSI is hosted within the Network List Manager service, also known as the Network Profile Manager. Previous OS iterations were hosted in the Network Location Awareness (NLA) service."

That is not a trivia point. It changes which binary you look at, which service you restart when you are testing, and which svchost group hosts the code. On a Windows 11 Enterprise device running build 26200.9168 the registry confirms it: both the NlaSvc and netprofm services have ServiceDll set to C:\Windows\System32\netprofmsvc.dll, and both have ImagePath of svchost.exe -k netprofm -p. There is no nlasvc.dll on disk at all.

Do not build detection on nlasvc.dll. A great deal of older guidance, including guidance still circulating, tells you to look for C:\Windows\System32\nlasvc.dll or to check the NetworkService svchost group. On current Windows 11 both are wrong. A Proactive Remediation detection script keyed on that file will report "not compliant" on every device in your estate forever. Verify binary names against the live OS before you ship logic that depends on them.

The race, and why negative caching makes it stick

The race itself is documented. Microsoft's Netlogon and Group Policy troubleshooting article says the behaviour "may be caused by a race condition between network initialization, locating a Domain Controller and processing Group Policy. If the network isn't available, a Domain Controller won't be located, and Group Policy processing will fail." The same article lists the underlying causes, and all of them apply equally to NLA's domain detection because both depend on the same DC reachability.

Now the part that turns a two-second glitch into a ten-minute outage: caching of the failure. Microsoft's article on the VPN variant of this bug spells out the sequence, and names two caches with documented defaults.

CacheDocumented defaultEffect on classification
Netlogon NegativeCachePeriod45 secondsAfter a failed DC discovery, Netlogon behaves as though the DCs are offline for this long. Domain detection retries during the window fail immediately.
DNS Client MaxNegativeCacheTtl5 secondsThe failed SRV lookup is cached, so the retry does not even reach DNS.

So the first attempt fails because the route or the DNS server was not ready yet. The failure is cached. The retry fails against the cache rather than the network. The device stays Public until something else forces a fresh evaluation.

The VPN case, which is chronic rather than occasional

Microsoft documents this specifically for third-party VPN clients, in KB4550028. The cause is "a time lag in some third-party VPN clients", and the lag "occurs when the client adds the necessary routes to the domain network".

The flow Microsoft describes is worth internalising because it is the same shape as the boot-time race, just triggered by a tunnel instead of a link-up. The VPN interface is created and gets an address. The VPN client is responsible for adding the routes that make the VPN DNS server reachable. The first route change already triggers NCSI detection and domain detection. If the SRV lookup happens before the route to the VPN DNS server exists, DsGetDcName returns ERROR_NO_SUCH_DOMAIN and that result is cached.

Gotcha: fast startup and hibernate resume look like boot but are not. On a device that resumes rather than cold boots, the adapter re-links and the classification runs again, with the same race. If your users almost never fully shut down, you will see this on resume far more often than on boot, and "did you restart it?" will appear to fix it because a real restart happens to win the race more often.

Registry: the whole NetworkList surface

Everything Windows remembers about networks lives under one parent key. Microsoft's support article confirms the location: "The information gathered by NLA is curated by the Network List Service (NLS) service and stored under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList."

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList
Subkey or valueTypeWhat it holds
Profiles\{GUID}keyOne key per remembered network. Microsoft documents this as containing "information about network profiles in Windows and the current category of the network profile".
Profiles\{GUID}CategoryREG_DWORDThe category. Microsoft's support article documents 0 as not an Active Directory network, 1 as an AD network this machine is not authenticated against, and 2 as an AD network this machine is authenticated against.
Profiles\{GUID}ProfileName, DescriptionREG_SZThe friendly network name shown in the UI, and its description.
Profiles\{GUID}ManagedREG_DWORDObserved on live devices as 1 for networks Windows recorded as domain-managed and 0 otherwise. Microsoft does not document this value name; treat it as a diagnostic hint, not a contract.
Profiles\{GUID}DateCreated, DateLastConnectedREG_BINARYFirst and most recent connection. Observed on live devices as a 16-byte little-endian SYSTEMTIME. Undocumented layout, so decode defensively.
Profiles\{GUID}NameTypeREG_DWORDPresent on every profile on live devices. Undocumented. Do not branch on it.
Signatures\ManagedkeyMicrosoft: "shows the managed network profiles stored in the Windows registry". One subkey per signature, named with a long hex string.
Signatures\UnmanagedkeyMicrosoft: "shows the unmanaged network profiles stored in the Windows registry".
Signatures\*\<hex>ProfileGuid, DnsSuffix, FirstNetwork, DefaultGatewayMac, SourcemixedThe fingerprint Windows uses to recognise a network again: the connection-specific DNS suffix, the first network name and the default gateway MAC. ProfileGuid is the join key back to Profiles. Value names observed on live devices; not individually documented.
Nla\IntranetEnabled, Nla\WirelesskeysPer-signature caches keyed by the same hex signature. Observed and undocumented.
PolicieskeyContainer for the Network List Manager Policies security settings. Empty when no such policy is applied.

Gotcha: Category lives on the profile, not on the signature. A lot of community guidance tells you to edit Category under Signatures\Unmanaged\<hex>. On Windows 11 25H2 that value does not exist there. Enumerating every subkey under both Signatures\Managed and Signatures\Unmanaged on a live device returns only ProfileGuid, Description, Source, DnsSuffix, FirstNetwork and DefaultGatewayMac. Category is under Profiles\{GUID}, which is also the only place Microsoft documents it. Verify the structure on your own build before you write a script against it.

One more genuine observation worth reporting: on a live domain-joined device, a profile with Managed = 1 and a signature under Signatures\Managed can still carry Category = 0. The device remembers the network as corporate and remembers the last category it settled on as Public. That combination in the registry is the fossil record of a flap.

System files, services and the scheduled task

These are the binaries actually in the flow. All of them were confirmed present on Windows 11 Enterprise 25H2, build 26200.9168, and the descriptions are the ones Windows itself reports in the file version resource.

FileWindows file descriptionRole in the flow
C:\Windows\System32\netprofmsvc.dllNetwork Profile Service DLLThe ServiceDll for both netprofm and NlaSvc. This is where the classification work now happens.
C:\Windows\System32\netprofm.dllNetwork List ManagerThe Network List Manager COM surface that applications and PowerShell talk to.
C:\Windows\System32\npmproxy.dllNetwork List Manager ProxyCOM proxy/stub for the Network List Manager interfaces.
C:\Windows\System32\nlmproxy.dllNetwork List Manager Public ProxySecond, public proxy for the same interface family.
C:\Windows\System32\nlaapi.dllNetwork Location Awareness 2The legacy NLA API surface, still shipped and still loaded by callers.
C:\Windows\System32\nlansp_c.dllNLA Namespace Service Provider DLLThe Winsock name-resolution service provider that exposes NLA to Winsock 2 apps.
C:\Windows\System32\mpssvc.dllMicrosoft Protection ServiceThe Windows Defender Firewall service that consumes the category and applies the profile.
C:\Windows\System32\FirewallAPI.dllWindows Defender Firewall APIWhat the firewall cmdlets and MMC snap-in call into.

The services, with their short and display names, and the state you should expect.

Short nameDisplay nameExpected state
netprofmNetwork List ServiceRunning, Manual start. Declares DependOnService of NSI, RpcSs, TcpIp. This is the one doing the work on Windows 11.
NlaSvcNetwork Location AwarenessManual start. May legitimately be Stopped on Windows 11. It declares no dependencies of its own and shares the netprofm svchost group. A stopped NlaSvc is not evidence of a fault here.
mpssvcWindows Defender FirewallRunning, Automatic. Depends on mpsdrv, bfe, nsi.
BFEBase Filtering EngineRunning, Automatic. If this is down the firewall cannot enforce anything.
nsiNetwork Store Interface ServiceRunning, Automatic. Carries the category down to the stack. Event 20002 in the log is literally "NSI Set Category Result".
DnscacheDNS ClientRunning, Automatic. Owns the negative cache that prolongs failures.
NetlogonNetlogonRunning on domain members. Owns NegativeCachePeriod.

There is exactly one scheduled task in this feature area, and it exists on Windows 11 today: \Microsoft\Windows\NlaSvc\WiFiTask. It runs %SystemRoot%\System32\WiFiTask.exe with the argument nla, and Windows describes it as a "Background task for performing per user and web interactions". It is a supporting task, not the classification engine, and there is nothing in it for you to tune. Do not disable it as a troubleshooting step.

Event Viewer: the complete catalog

Four channels matter, and two of them are where you will spend your time. Provider metadata below was read from the live providers on Windows 11 25H2, so these are the real IDs and the real message templates.

Microsoft-Windows-NetworkProfile/Operational  (also /Diagnostic)
IDMessage templateWhy you care
4001 / 4002 / 4003Entered State / Transitioning to State, with Interface GuidThe identification state machine walking forward. Noisy but it timestamps the sequence.
4004Network State Change Fired, including "Domain Connectivity Level Changed"Tells you a domain connectivity transition was signalled to listeners.
10000Network Connected - Name, Desc, Type, State, CategoryThe primary evidence. Carries the category at the moment of connection. Look for Name "Identifying..." with Category Public.
10001Network Disconnected - same fieldsPairs with 10000 to bound each connection episode.
10002Network Category Changed - same fieldsThe flap itself. One of these shortly after a 10000 that said Public is the correction you were looking for.
10003 - 10008Posting / Posted Network Connected, Profile, Disconnected Event, with ProfileIDNotification plumbing. Useful for correlating a profile GUID to an episode.
20001NLM service initialization failed (error=%1)Rare and serious. If you see this, stop looking at the race.
20002NSI Set Category Result - Profile GUID, Interface GUID, Network Category, IPv4 Error Code, IPv6 Error Code, ContextThe moment the category is pushed into the network stack, with per-family error codes.
20005Url %1 is of incorrect formatA malformed NCSI or domain-location URL you configured by policy.
Microsoft-Windows-NlaSvc/Operational  (also /Diagnostic)
IDMessage templateWhy you care
4101 / 4102Received WMI Media Connect / Disconnect NotificationThe link-state trigger. This is where an episode begins.
4103 / 4104Route change / Address change has occurred for interfaceThe VPN trigger. KB4550028's "first route change" is this event.
4106 / 4261Received DHCP notification / DHCP has stabilized for %1Whether addressing had settled before detection ran.
4203 / 4204 / 4205Start / Stop / failed gateway resolution on interfaceDefault gateway MAC resolution, which feeds the network signature.
4301 / 4302Start / Stop Intranet resolverBrackets the domain-detection attempt.
4311 / 4312 / 4313Start / Stop / failed DsGetDcName for DnsSuffix, with error, domain and forestStep 3 of the chain. A 4313 is your SRV lookup failing.
4321 - 4323DsGetDcName for DS infoSecond DC lookup, for directory information.
4331 - 4333DsGetDcName for root domain GUIDForest root lookup. Fails in multi-forest and split-DNS designs.
4341 / 4342 / 4343Start / Stop / failed LDAP authentication on interface, with try count and errorSteps 4 and 5. A 4343 is your bind failing. This is the event that decides Public versus Domain.
4351 - 4356ldap_connect and ldap_bind per DC, with attempt number and errorPer-DC detail underneath 4343. Tells you whether it was reachability or the bind.
4401 / 4402 / 4403 / 4405 / 4410Inserting identifying / identified signature, Removing identified signature, with Source and SignatureSignature churn. Repeated insert-remove pairs for the same network is flapping in raw form.
4407 / 4408Adding / Removing interfaceAdapter arrival and departure, including VPN adapters.
4451Network on %1 is unlikely to be authentication-capable; authentication will continue in the background. Reason: %2Windows telling you it has given up in the foreground. Exactly the state in which you get Public.

The other two channels are Microsoft-Windows-NCSI/Operational and Microsoft-Windows-NCSI/Analytic for connectivity-level questions, and Microsoft-Windows-NetworkLocationWizard/Operational for the interactive "make this network private" prompt. Neither decides the Domain category.

There is no dedicated log file for classification. This feature area writes to ETW channels, not to a text log, so there is no equivalent of CBS.log to grep. The closest thing to a file-based trace is %windir%\debug\netlogon.log, which Microsoft documents as recording lines such as NlDiscoverDc: Cannot find DC and NlSessionSetup: Session setup: cannot pick trusted DC for the underlying DC-location failure. For a full capture Microsoft's supported path is the TSS toolset with .\TSS.ps1 -Scenario NET_NCSI.

How to verify: read the category, then read the events

Work in this order. Current state first, because it is one command and it either exonerates or convicts the theory immediately.

This first command asks Windows what category each connected network is in right now, and what that means for the firewall. Get-NetConnectionProfile returns one object per connected network; NetworkCategory is the documented property, with accepted values Public, Private and DomainAuthenticated.

PowerShell - run elevated
Get-NetConnectionProfile | Select-Object InterfaceAlias, Name, NetworkCategory, IPv4Connectivity # HEALTHY on a domain-joined device on the corporate LAN: # NetworkCategory : DomainAuthenticated -> the Domain firewall profile is live # BROKEN: NetworkCategory reads Public while the device is plainly on the LAN. # Also broken, and easy to miss: Name reads "Unidentified network". Get-NetFirewallProfile -All | Select-Object Name, Enabled, DefaultInboundAction # This shows the profiles that EXIST and whether each is enabled. # It does NOT tell you which one is active - the category above decides that. # Windows applies a profile per network, so two can be in force at once.

If the category is wrong, walk the same three steps Windows walks. Each command below tests exactly one link in the chain, so whichever one fails first is your root cause.

PowerShell - run elevated
# Step 3: can the device locate a DC at all? /force skips the cached answer. nltest /dsgetdc:contoso.com /force # HEALTHY: a DC name, an Address, Dom Name, Forest Name, Dc Site Name, then # "The command completed successfully". # BROKEN: "DsGetDcName function Failed with ERROR_NO_SUCH_DOMAIN" - the SRV # lookup for _ldap._tcp.<site>._sites.dc._msdcs.<domain> did not resolve. # Step 4: can the device open TCP 389 to that DC? Ensure 389 is allowed outbound. Test-NetConnection -ComputerName dc01.contoso.com -Port 389 -InformationLevel Detailed # HEALTHY: TcpTestSucceeded : True # BROKEN: TcpTestSucceeded : False -> detection cannot proceed and the device # cannot identify the domain network, no matter how correct DNS was. # Step 5: did the LDAP bind succeed? Ask the log, not the network. Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-NlaSvc/Operational'; Id=4341,4342,4343,4451 } -MaxEvents 20 | Select-Object TimeCreated, Id, Message | Format-List # HEALTHY: 4341 Start then 4342 Stop, with no 4343 in between. # BROKEN: 4343 "LDAP authentication on interface ... failed with error 0x...". # Quote that hex code verbatim in a support case. Do not guess at its meaning.

Now the timeline. This is the query that proves flapping happened, and when.

PowerShell - run elevated
Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-NetworkProfile/Operational' Id = 10000, 10001, 10002 StartTime = (Get-Date).AddDays(-7) } -MaxEvents 100 | Sort-Object TimeCreated | Select-Object TimeCreated, Id, @{ n='Detail'; e={ ($_.Message -replace '\s+',' ').Trim() } } | Format-Table -AutoSize -Wrap # READ IT LIKE THIS: find a 10000 whose Category is Public, then look for the # next 10002 for the same network name. The gap between the two timestamps is # the exact window in which your Domain-scoped rules were not in force. # Many 10002 events per day for the same corporate network = chronic flapping.

Gotcha: an empty event list is not a clean bill of health. These operational channels can be disabled, and they are small enough to wrap in hours on a busy device. Before you conclude "no flapping occurred", check (Get-WinEvent -ListLog 'Microsoft-Windows-NetworkProfile/Operational').IsEnabled and .RecordCount. A disabled channel returns nothing and looks identical to a healthy device. The companion script below checks and reports both for exactly this reason.

Finally, the registry. This is where you find evidence of a flap that happened before the event channel wrapped, because the stored profile keeps the last category it settled on.

Registry Editor
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles\{aaaaaaaa-0b0b-1c1c-2d2d-333333333333}
ProfileName       REG_SZ       contoso.com
Description       REG_SZ       contoso.com
Managed           REG_DWORD    0x00000001  (recorded as a domain-managed network)
Category          REG_DWORD    0x00000000  (Public - the fossil of a flap)
DateCreated       REG_BINARY   e8 07 0a 00 ...  (SYSTEMTIME, observed layout)
DateLastConnected REG_BINARY   ea 07 08 00 ...
Illustrative, modelled on a genuine device with the GUID and network name replaced. A Managed of 1 alongside a Category of 0 is the combination to hunt for.

The fix: shrink the window, then stop depending on the DC

There are two families of mitigation and they are not alternatives. The first shrinks the race window so the device is far more likely to classify correctly on the first attempt. The second removes the dependency on DC reachability entirely for the purpose of naming the network. Do the first everywhere. Do the second if you have remote and VPN users, which you do.

Fix 1: make startup wait for the network

The setting is "Always wait for the network at computer startup and logon", and it is worth being precise about what it does, because its name oversells it. It does not set a firewall profile and it does not force a category. What it changes is whether Group Policy processing is synchronous. Microsoft's wording: "If you enable this policy setting, computers wait for the network to be fully initialized before users are logged on. Group Policy is applied in the foreground, synchronously." By default on client computers that processing is asynchronous, users log on with cached credentials, and policy is applied in the background afterwards.

The reason it helps here is indirect but real: holding logon until the network is genuinely initialised means the domain-detection attempt is far less likely to run before routes, DNS and DC reachability exist. It buys the classification a fair race. The cost is slower logons, and you should measure that before you deploy it broadly.

In the Group Policy Editor:

Computer ConfigurationAdministrative TemplatesSystemLogon
  1. Open the Group Policy Management Console on a management workstation, or gpedit.msc for a single machine.
  2. Create or edit a GPO linked to the OU holding your domain-joined Windows 11 devices.
  3. Expand Computer Configuration, then Policies, then Administrative Templates, then System, then Logon.
  4. Double-click Always wait for the network at computer startup and logon.
  5. Select Enabled, then Apply and OK.
  6. On a test device run gpupdate /force, restart twice, and confirm the value at HKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Winlogon value name SyncForegroundPolicy.

In Intune this is an ADMX-backed policy, so it goes in as a custom OMA-URI rather than a Settings Catalog toggle:

intune.microsoft.comDevicesConfigurationCreateWindows 10 and later > Templates > Custom
  1. Sign in to intune.microsoft.com as at least an Intune Administrator.
  2. Go to Devices, then Configuration, then Create, then New policy.
  3. Platform Windows 10 and later, profile type Templates, then Custom, then Create.
  4. Name it something you will recognise in six months, such as Win11 - Wait for network at startup.
  5. On Configuration settings choose Add.
  6. OMA-URI: ./Device/Vendor/MSFT/Policy/Config/ADMX_Logon/SyncForegroundPolicy
  7. Data type String. The value is the ADMX-backed enable payload, <enabled/>. Microsoft's "Understanding ADMX-backed policies" page has the exact SyncML shape if you need to wrap it.
  8. Save, assign to a pilot group of no more than twenty devices, and create the profile.
  9. After a sync, confirm on a device with the same registry check as step 6 above.

Test logon time before you go wide. Enabling synchronous foreground processing on a fleet with slow WAN links, 802.1X, or NAC can add tens of seconds to every boot and every logon. Microsoft also notes this setting is ignored at computer startup on Windows Server 2008 and later, so do not deploy it to servers expecting it to change anything there. Pilot on a small group, measure, then expand. Rolling this out estate-wide on a Friday afternoon is how you convert a firewall problem into a productivity incident.

Fix 2: give Group Policy explicit wait times

Two related policies let you override the wait times Windows computes for itself. Microsoft's Netlogon and Group Policy article recommends both by name for exactly this class of problem: "Specify startup policy processing wait time" for corporate LAN and WLAN, and "Specify workplace connectivity wait time for policy processing" for external LAN and WLAN.

Computer ConfigurationAdministrative TemplatesSystemGroup Policy
  1. In the same GPO, expand Computer Configuration, then Policies, then Administrative Templates, then System, then Group Policy.
  2. Open Specify startup policy processing wait time, set Enabled, and enter a value in minutes. The ADMX permits 1 to 600. Base it on how long your slowest site actually takes to reach a DC, measured, not guessed.
  3. Open Specify workplace connectivity wait time for policy processing, set Enabled, and enter a value in seconds. Same 1 to 600 range. This is the one that matters for VPN and Always On VPN users.
  4. Both write to HKLM\SOFTWARE\Policies\Microsoft\Windows\System, as GpNetworkStartTimeoutPolicyValue and CorpConnStartTimeoutPolicyValue.

Note the different units. The startup policy is expressed in minutes and the workplace connectivity policy in seconds. Getting that backwards is a very easy way to configure a ten-hour wait.

Fix 3: stop caching the failure

This is Microsoft's documented workaround for the VPN variant, and it is the one to reach for when the classification does not self-correct rather than merely correcting late. KB4550028's instruction is to "disable negative cache to help the Network Location Awareness (NLA) service when it retries domain detection".

KeyValueSetting
HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\ParametersNegativeCachePeriodREG_DWORD. Documented default 45 seconds. Microsoft says set to 0 to disable caching, and separately suggests trying a low value such as 3 seconds first.
HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\ParametersMaxNegativeCacheTtlREG_DWORD. Documented default 5 seconds. Set to 0 to disable, and only if the Netlogon change alone did not resolve it.

These two changes increase load and are the wrong first move. Disabling negative caching means every failed DC or DNS lookup is retried against the network instead of answered from cache. On a site with an intermittent DC, or on a large fleet behind a slow link, that is real extra traffic. Microsoft's own recommended resolution for the VPN case is to contact the VPN vendor to reduce the route-add lag, and it offers the callback APIs (NotifyUnicastIpAddressChange, NotifyIpInterfaceChange, NotifyAddrChange) that a well-behaved client should use. Apply the registry workaround as a targeted mitigation for affected devices, document it, and take the vendor conversation seriously. Back up the registry before you change either value.

Fix 4: the modern answer, and the one to actually plan for

Everything above makes the DC-dependent race more likely to be won. This one removes the dependency. The NetworkListManager Policy CSP lets you nominate an internal HTTPS endpoint; if the device can resolve and reach it over HTTPS, "the network would be considered authenticated" and you supply the name that network is given. Microsoft's firewall documentation points at this explicitly as "another option to detect the domain network", and notes that it "applies to Microsoft Entra joined devices too".

SettingOMA-URINotes
AllowedTlsAuthenticationEndpoints./Device/Vendor/MSFT/Policy/Config/NetworkListManager/AllowedTlsAuthenticationEndpointsString, list delimited by Unicode 0xF000. Windows 10 20H2 and later.
ConfiguredTlsAuthenticationNetworkName./Device/Vendor/MSFT/Policy/Config/NetworkListManager/ConfiguredTlsAuthenticationNetworkNameString. Names the authenticated network. Windows 10 20H2 and later.
UnidentifiedNetworks_LocationType./Device/Vendor/MSFT/Policy/Config/NetworkListManager/UnidentifiedNetworks_LocationTypeInteger. 0 Public (default), 1 Private. Windows 11 22H2 with KB5053657, and Windows 11 24H2 and later.
IdentifyingNetworks_LocationType./Device/Vendor/MSFT/Policy/Config/NetworkListManager/IdentifyingNetworks_LocationTypeInteger. 0 Public (default), 1 Private. Covers the transient "Identifying..." state you saw in the event log.
UnidentifiedNetworks_UserPermissions./Device/Vendor/MSFT/Policy/Config/NetworkListManager/UnidentifiedNetworks_UserPermissionsInteger. 0 user can change location (default), 1 user cannot.
AllNetworks_NetworkLocation / _NetworkName / _NetworkIcon./Device/Vendor/MSFT/Policy/Config/NetworkListManager/AllNetworks_NetworkLocation and siblingsInteger. 0 user can change (default), 1 user cannot.

Microsoft's requirements for the endpoint are specific, and every one of them is a real-world failure mode if you skip it. The HTTPS endpoint must not require any further authentication such as sign-in or MFA. It must be an internal address not reachable from outside the organisational network. The client must trust the server certificate, so the issuing CA must be in the machine root store. The certificate must not be a public certificate. Microsoft's own test is that Invoke-WebRequest -Uri https://nls.corp.contoso.com -Method get -UseBasicParsing -MaximumRedirection 0 returns StatusCode 200.

intune.microsoft.comDevicesConfigurationCreateSettings catalog
  1. Stand up the internal HTTPS endpoint first and prove it with the Invoke-WebRequest test above from a client that trusts your internal CA. Do not configure policy against an endpoint you have not tested.
  2. In intune.microsoft.com go to Devices, then Configuration, then Create, then New policy.
  3. Platform Windows 10 and later, profile type Settings catalog, then Create.
  4. Name it, for example Win11 - Network List Manager TLS authentication.
  5. On Configuration settings choose Add settings and search the picker for Network List Manager.
  6. Select Allowed Tls Authentication Endpoints and Configured Tls Authentication Network Name. Add Unidentified Networks Location Type and Identifying Networks Location Type if you also want to control those.
  7. Fill in your endpoint URL or URLs, and the network name. If you use Always On VPN Trusted Network Detection, the name must be the DNS suffix configured in the profile's TrustedNetworkDetection attribute, because that is what the VPN stack compares against.
  8. If the setting is not in your tenant's picker, fall back to a Custom profile with the OMA-URIs in the table. For a custom profile Microsoft's documented list format is <![CDATA[https://nls.corp.contoso.com&#xF000;https://nls.corp.fabricam.com]]>.
  9. Assign to a pilot group, sync a device, and verify with Get-NetConnectionProfile that the network now reports the name you configured.

The honest Intune reality: there is no way to force the Domain category. The NetworkListManager CSP's location-type settings accept exactly two values, Public and Private. There is no Domain option, in the CSP or in the Settings Catalog, because Microsoft's design is that Domain is earned and "cannot be set manually". The TLS endpoint policy makes a network authenticated and gives it a name you control, which is what Trusted Network Detection and your own tooling can key on. It is not a synonym for the Domain firewall profile. Anyone who tells you a CSP can pin the Domain profile is mistaken, and the honest answer to "can we just force it in Intune?" is no.

Fix 5: the second, different GPO location

This is the one people miss, because it is not in Administrative Templates at all. Network List Manager Policies is a security extension. Microsoft documents the location precisely: "The Network List Manager Policies are located at the following path in Group Policy Object Editor: Computer Configuration | Windows Settings | Security Settings | Network List Manager Policies."

Computer ConfigurationWindows SettingsSecurity SettingsNetwork List Manager Policies
  1. In the GPO editor expand Computer Configuration, then Windows Settings, then Security Settings, then Network List Manager Policies.
  2. Open Unidentified Networks. On the Network Name tab set Location type to Private or Public, and set User permissions to allow or block users changing it.
  3. Open Identifying Networks and set its Location type. This governs the temporary state while Windows is still working the network out, which is the "Identifying..." entry in your event log.
  4. Open All Networks to control whether users can change the network name, location or icon for any network.
  5. Because this is a security extension rather than an ADMX template, there is no Administrative Templates path and no documented registry value name to verify against. Confirm the applied result with Get-NetConnectionProfile and with gpresult /h, not by hunting for a registry value.

Setting unidentified networks to Private is a real security decision, not a workaround. Microsoft's own guidance on the Private option is blunt: "Do not select this item if there is a possibility that an active, unidentified network is in a public place." Every laptop that joins an airport or hotel Wi-Fi and fails to identify it will now get your Private rule set instead of your Public one. On a fleet of mobile devices that is a meaningful widening of exposure. If you set it, pair it with a Private profile that is genuinely tight, and prefer Fix 4 as the primary answer.

Fix 6: for VPN fleets, wire up Trusted Network Detection

If you run Always On VPN, the classification problem and the tunnel-trigger problem are the same problem. Trusted Network Detection is configured through VPNv2/<ProfileName>/TrustedNetworkDetection in the VPNv2 CSP and takes a list of DNS suffixes. The VPN stack compares the physical interface's connection profile against that list; if it matches and the network is Private or provisioned by MDM, the VPN does not trigger. That is why Microsoft's CSP documentation says the ConfiguredTlsAuthenticationNetworkName value "must be the DNS suffix that is configured in the TrustedNetworkDetection attribute" when you use the two together. Configure them as a pair or neither will behave the way you expect.

Tip: force a re-evaluation without rebooting. Microsoft's troubleshooting guidance notes that disabling and re-enabling the adapter, or restarting the Network List Service, triggers a fresh NLA domain-detection pass, and that in some scenarios this alone resolves the issue. That gives you a two-minute test loop instead of a five-minute reboot loop while you validate a fix. It also gives you the clean window to capture a trace in, because you control when detection starts. Bear in mind that a restart of netprofm is a change to a running service, so keep it to test devices and out of any read-only diagnostic you hand to a service desk.

Proof it worked: a real run on a real device

The companion script for this post is Get-NetworkCategoryHistory.ps1. It is read-only by design: it never sets a category, never touches a firewall setting, never starts or stops a service and never writes a registry value. It gathers the current category per interface, the firewall profile state, the stored NetworkList profiles with decoded connect times, the policy state for every setting discussed above, and the recent identification events, then gives you a flapping verdict.

It fails loud. If it is not elevated it aborts rather than printing empty tables that look like a healthy device, and if any individual read fails it says so and exits non-zero rather than letting you read a partial report as a clean one.

The following is genuine output from an elevated run on Windows 11 Enterprise 25H2, build 26200.9168, with the computer name, network names and interface GUIDs replaced. Nothing here is invented.

PowerShell - real run, identifiers replaced
PS> .\Get-NetworkCategoryHistory.ps1 -EventDays 30 -MaxEvents 25 Computer CONTOSO-1234 Running elevated True OS Microsoft Windows 11 Enterprise Display version / build 25H2 / 26200.9168 netprofm ServiceDll C:\WINDOWS\System32\netprofmsvc.dll netprofm DependOnService NSI, RpcSs, TcpIp NlaSvc ServiceDll C:\WINDOWS\System32\netprofmsvc.dll NlaSvc DependOnService none declared # Both services point at netprofmsvc.dll. There is no nlasvc.dll on this build. InterfaceAlias NetworkName NetworkCategory FirewallProfile IPv4Connectivity -------------- ----------- --------------- --------------- ---------------- Wi-Fi GUEST-WIFI Public Public Internet # Off the corporate network, so Public is CORRECT here. On the LAN this line # should read DomainAuthenticated / Domain. Stored profiles found 18 ProfileName Category Managed Signature FirstSeen LastConnected ----------- -------- ------- --------- --------- ------------- GUEST-WIFI 0 (Public / not an AD network) 0 Unmanaged 2026-07-27 11:08 2026-08-21 20:10 corp.contoso.com 0 (Public / not an AD network) 1 Managed 2024-10-17 16:11 2026-08-21 14:51 corp.contoso.com 2 absent 1 Managed 2024-10-18 08:34 2026-08-16 11:16 # THIS is the finding. Managed=1 means Windows recorded a domain-managed network, # yet the stored Category is 0 (Public). The device settled on Public last time. # And the same corporate name appears twice: it was re-identified as a new # network, which is the classic flapping fingerprint. SyncForegroundPolicy (policy) not configured (asynchronous startup - the default) Netlogon NegativeCachePeriod 0 NetworkList\Policies key exists but is empty (no NLM security policy applied) # Wait-for-network is OFF and no Network List Manager policy is applied, so this # device has no mitigation in place at all. Negative caching is already disabled.

The second half of the run is the event timeline, and this is where the mechanism stops being theory.

PowerShell - real run, identifiers replaced
Channel: Microsoft-Windows-NetworkProfile/Operational Enabled True Record count 2198 # Channel enabled with 2198 records, so an empty result below would be real. Time Id Message ---- -- ------- 20:10:44 10000 Network Connected Name: Identifying... Type: Unmanaged Category: Public 20:10:59 20002 NSI Set Category Result Profile GUID: {ffffffff-...} Network Categor... 14:51:37 10000 Network Connected Name: corp.contoso.com Type: Managed Category: Domain Authenticated 14:51:37 10002 Network Category Changed Name: corp.contoso.com Type: Managed Category: Domain Authenticated # "Identifying..." connected with Category: Public is the transient state. # The 10002 at 14:51:37 is the correction to Domain Authenticated. Channel: Microsoft-Windows-NlaSvc/Operational Record count 2114 Time Id Level Message ---- -- ----- ------- 20:13:12 4343 Error LDAP authentication on interface {GUID} (NULL) failed with error 0x51 20:12:44 4343 Error LDAP authentication on interface {GUID} (NULL) failed with error 0xA00804C7 # Step 5 of the chain failing, repeatedly, while off the corporate network. # Quote these hex codes verbatim in a support case. Do not guess their meaning. ============================================================================== 7. Flapping verdict ============================================================================== 1 category-change event(s) (ID 10002) in the last 30 day(s): 14:51:37 Network Category Changed Name: corp.contoso.com Category: Domain Authenticated All reads succeeded. Nothing on this device was modified by this script.

That is the whole diagnosis in one screen. The device is domain-managed. It remembers the corporate network twice. The stored category on the managed profile is Public. Domain detection was failing with LDAP errors while off-network, and when it did succeed it succeeded as a category change rather than as the initial classification. No mitigation is configured. If a user on this device reported that a Domain-scoped rule was not working after a boot, you would now be able to say when, for how long, and why.

Grab the script here: github.com/Imran76Awan/Windows-11-Scripts. Run it elevated. It changes nothing.

References

No community or MVP deep-dive on this specific mechanism verified as both reachable and genuinely on topic during research for this post, so no MVP reference table is included rather than risk pointing you at something that does not cover it.

PowerShell — companion script

Download it from Imran76Awan/Windows-11-Scripts — no sign-in required. It is read-only: it reports and never changes a device or anything in Intune. Validate it in your own environment before relying on the output.

Get-NetworkCategoryHistory.ps1 — Read-only report on Windows network classification: current network category per
View all scripts on GitHub
Was this post helpful?
React below — no account needed
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows 11
Hardening Remote Desktop on Windows 11: NLA, encryption level,…
Enabling RDP is one toggle. Hardening it is a dozen settings across the registry, Group…
Windows 11
Windows Search finds nothing, or eats the disk: the index, its…
The Windows Search index is a real database on disk, and most search failures are a…
Windows 11
Reliability Monitor: the built-in view that answers "what…
Reliability Monitor puts crashes, bugchecks, driver installs and update installs on one…