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.
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 network status shows as "Unidentified network" in the system tray.
- An incorrect firewall profile is applied. The Public profile applies even though the machine is domain-joined.
- Firewall rules configured under the Domain profile are not applied, causing connectivity failures.
- Connectivity to internal applications fails because the Domain profile is not active.
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.
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.
- 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.
- That change triggers NCSI detection, which works out the connectivity level.
- In parallel, domain detection starts. The service calls the
DsGetDcNamefunction 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>. - If DNS returns a DC, the machine opens a TCP connection to that DC on port 389.
- Inside that connection it sends an LDAP bind request. Only when the bind succeeds does the machine "identify itself in the domain network".
- 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.
| Constant | Value | Meaning (Microsoft wording) |
|---|---|---|
NLM_NETWORK_CATEGORY_PUBLIC | 0 | The network is a public (untrusted) network. |
NLM_NETWORK_CATEGORY_PRIVATE | 0x1 | The network is a private (trusted) network. |
NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED | 0x2 | The 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.
| Constant | Value | Meaning (Microsoft wording) |
|---|---|---|
NLM_DOMAIN_TYPE_NON_DOMAIN_NETWORK | 0 | The Network is not an Active Directory Network. |
NLM_DOMAIN_TYPE_DOMAIN_NETWORK | 0x1 | The Network is an Active Directory Network, but this machine is not authenticated against it. |
NLM_DOMAIN_TYPE_DOMAIN_AUTHENTICATED | 0x2 | The 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.
- The network stack and adapter initialisation start at roughly the same time, and some adapters and switches have link arbitration and MAC uniqueness checks that take longer than the wait allowed.
- 802.1X authentication delays connections to domain controllers.
- The client waits on DHCP for an address, which delays the interface appearing at all.
- Health-verification solutions (NAC and similar) hold the new member in a quarantine network first.
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.
| Cache | Documented default | Effect on classification |
|---|---|---|
Netlogon NegativeCachePeriod | 45 seconds | After 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 MaxNegativeCacheTtl | 5 seconds | The 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."
| Subkey or value | Type | What it holds |
|---|---|---|
Profiles\{GUID} | key | One 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} → Category | REG_DWORD | The 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, Description | REG_SZ | The friendly network name shown in the UI, and its description. |
Profiles\{GUID} → Managed | REG_DWORD | Observed 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, DateLastConnected | REG_BINARY | First and most recent connection. Observed on live devices as a 16-byte little-endian SYSTEMTIME. Undocumented layout, so decode defensively. |
Profiles\{GUID} → NameType | REG_DWORD | Present on every profile on live devices. Undocumented. Do not branch on it. |
Signatures\Managed | key | Microsoft: "shows the managed network profiles stored in the Windows registry". One subkey per signature, named with a long hex string. |
Signatures\Unmanaged | key | Microsoft: "shows the unmanaged network profiles stored in the Windows registry". |
Signatures\*\<hex> → ProfileGuid, DnsSuffix, FirstNetwork, DefaultGatewayMac, Source | mixed | The 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\Wireless | keys | Per-signature caches keyed by the same hex signature. Observed and undocumented. |
Policies | key | Container 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.
| File | Windows file description | Role in the flow |
|---|---|---|
C:\Windows\System32\netprofmsvc.dll | Network Profile Service DLL | The ServiceDll for both netprofm and NlaSvc. This is where the classification work now happens. |
C:\Windows\System32\netprofm.dll | Network List Manager | The Network List Manager COM surface that applications and PowerShell talk to. |
C:\Windows\System32\npmproxy.dll | Network List Manager Proxy | COM proxy/stub for the Network List Manager interfaces. |
C:\Windows\System32\nlmproxy.dll | Network List Manager Public Proxy | Second, public proxy for the same interface family. |
C:\Windows\System32\nlaapi.dll | Network Location Awareness 2 | The legacy NLA API surface, still shipped and still loaded by callers. |
C:\Windows\System32\nlansp_c.dll | NLA Namespace Service Provider DLL | The Winsock name-resolution service provider that exposes NLA to Winsock 2 apps. |
C:\Windows\System32\mpssvc.dll | Microsoft Protection Service | The Windows Defender Firewall service that consumes the category and applies the profile. |
C:\Windows\System32\FirewallAPI.dll | Windows Defender Firewall API | What the firewall cmdlets and MMC snap-in call into. |
The services, with their short and display names, and the state you should expect.
| Short name | Display name | Expected state |
|---|---|---|
netprofm | Network List Service | Running, Manual start. Declares DependOnService of NSI, RpcSs, TcpIp. This is the one doing the work on Windows 11. |
NlaSvc | Network Location Awareness | Manual 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. |
mpssvc | Windows Defender Firewall | Running, Automatic. Depends on mpsdrv, bfe, nsi. |
BFE | Base Filtering Engine | Running, Automatic. If this is down the firewall cannot enforce anything. |
nsi | Network Store Interface Service | Running, Automatic. Carries the category down to the stack. Event 20002 in the log is literally "NSI Set Category Result". |
Dnscache | DNS Client | Running, Automatic. Owns the negative cache that prolongs failures. |
Netlogon | Netlogon | Running 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.
| ID | Message template | Why you care |
|---|---|---|
| 4001 / 4002 / 4003 | Entered State / Transitioning to State, with Interface Guid | The identification state machine walking forward. Noisy but it timestamps the sequence. |
| 4004 | Network State Change Fired, including "Domain Connectivity Level Changed" | Tells you a domain connectivity transition was signalled to listeners. |
| 10000 | Network Connected - Name, Desc, Type, State, Category | The primary evidence. Carries the category at the moment of connection. Look for Name "Identifying..." with Category Public. |
| 10001 | Network Disconnected - same fields | Pairs with 10000 to bound each connection episode. |
| 10002 | Network Category Changed - same fields | The flap itself. One of these shortly after a 10000 that said Public is the correction you were looking for. |
| 10003 - 10008 | Posting / Posted Network Connected, Profile, Disconnected Event, with ProfileID | Notification plumbing. Useful for correlating a profile GUID to an episode. |
| 20001 | NLM service initialization failed (error=%1) | Rare and serious. If you see this, stop looking at the race. |
| 20002 | NSI Set Category Result - Profile GUID, Interface GUID, Network Category, IPv4 Error Code, IPv6 Error Code, Context | The moment the category is pushed into the network stack, with per-family error codes. |
| 20005 | Url %1 is of incorrect format | A malformed NCSI or domain-location URL you configured by policy. |
| ID | Message template | Why you care |
|---|---|---|
| 4101 / 4102 | Received WMI Media Connect / Disconnect Notification | The link-state trigger. This is where an episode begins. |
| 4103 / 4104 | Route change / Address change has occurred for interface | The VPN trigger. KB4550028's "first route change" is this event. |
| 4106 / 4261 | Received DHCP notification / DHCP has stabilized for %1 | Whether addressing had settled before detection ran. |
| 4203 / 4204 / 4205 | Start / Stop / failed gateway resolution on interface | Default gateway MAC resolution, which feeds the network signature. |
| 4301 / 4302 | Start / Stop Intranet resolver | Brackets the domain-detection attempt. |
| 4311 / 4312 / 4313 | Start / Stop / failed DsGetDcName for DnsSuffix, with error, domain and forest | Step 3 of the chain. A 4313 is your SRV lookup failing. |
| 4321 - 4323 | DsGetDcName for DS info | Second DC lookup, for directory information. |
| 4331 - 4333 | DsGetDcName for root domain GUID | Forest root lookup. Fails in multi-forest and split-DNS designs. |
| 4341 / 4342 / 4343 | Start / Stop / failed LDAP authentication on interface, with try count and error | Steps 4 and 5. A 4343 is your bind failing. This is the event that decides Public versus Domain. |
| 4351 - 4356 | ldap_connect and ldap_bind per DC, with attempt number and error | Per-DC detail underneath 4343. Tells you whether it was reachability or the bind. |
| 4401 / 4402 / 4403 / 4405 / 4410 | Inserting identifying / identified signature, Removing identified signature, with Source and Signature | Signature churn. Repeated insert-remove pairs for the same network is flapping in raw form. |
| 4407 / 4408 | Adding / Removing interface | Adapter arrival and departure, including VPN adapters. |
| 4451 | Network on %1 is unlikely to be authentication-capable; authentication will continue in the background. Reason: %2 | Windows 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.
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.
Now the timeline. This is the query that proves flapping happened, and when.
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.
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:
- Open the Group Policy Management Console on a management workstation, or
gpedit.mscfor a single machine. - Create or edit a GPO linked to the OU holding your domain-joined Windows 11 devices.
- Expand Computer Configuration, then Policies, then Administrative Templates, then System, then Logon.
- Double-click Always wait for the network at computer startup and logon.
- Select Enabled, then Apply and OK.
- On a test device run
gpupdate /force, restart twice, and confirm the value atHKLM\SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Winlogonvalue nameSyncForegroundPolicy.
In Intune this is an ADMX-backed policy, so it goes in as a custom OMA-URI rather than a Settings Catalog toggle:
- Sign in to intune.microsoft.com as at least an Intune Administrator.
- Go to Devices, then Configuration, then Create, then New policy.
- Platform Windows 10 and later, profile type Templates, then Custom, then Create.
- Name it something you will recognise in six months, such as Win11 - Wait for network at startup.
- On Configuration settings choose Add.
- OMA-URI:
./Device/Vendor/MSFT/Policy/Config/ADMX_Logon/SyncForegroundPolicy - 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. - Save, assign to a pilot group of no more than twenty devices, and create the profile.
- 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.
- In the same GPO, expand Computer Configuration, then Policies, then Administrative Templates, then System, then Group Policy.
- 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.
- 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.
- Both write to
HKLM\SOFTWARE\Policies\Microsoft\Windows\System, asGpNetworkStartTimeoutPolicyValueandCorpConnStartTimeoutPolicyValue.
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".
| Key | Value | Setting |
|---|---|---|
HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters | NegativeCachePeriod | REG_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\Parameters | MaxNegativeCacheTtl | REG_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".
| Setting | OMA-URI | Notes |
|---|---|---|
| AllowedTlsAuthenticationEndpoints | ./Device/Vendor/MSFT/Policy/Config/NetworkListManager/AllowedTlsAuthenticationEndpoints | String, list delimited by Unicode 0xF000. Windows 10 20H2 and later. |
| ConfiguredTlsAuthenticationNetworkName | ./Device/Vendor/MSFT/Policy/Config/NetworkListManager/ConfiguredTlsAuthenticationNetworkName | String. Names the authenticated network. Windows 10 20H2 and later. |
| UnidentifiedNetworks_LocationType | ./Device/Vendor/MSFT/Policy/Config/NetworkListManager/UnidentifiedNetworks_LocationType | Integer. 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_LocationType | Integer. 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_UserPermissions | Integer. 0 user can change location (default), 1 user cannot. |
| AllNetworks_NetworkLocation / _NetworkName / _NetworkIcon | ./Device/Vendor/MSFT/Policy/Config/NetworkListManager/AllNetworks_NetworkLocation and siblings | Integer. 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.
- Stand up the internal HTTPS endpoint first and prove it with the
Invoke-WebRequesttest above from a client that trusts your internal CA. Do not configure policy against an endpoint you have not tested. - In intune.microsoft.com go to Devices, then Configuration, then Create, then New policy.
- Platform Windows 10 and later, profile type Settings catalog, then Create.
- Name it, for example Win11 - Network List Manager TLS authentication.
- On Configuration settings choose Add settings and search the picker for Network List Manager.
- 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.
- 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
TrustedNetworkDetectionattribute, because that is what the VPN stack compares against. - 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https://nls.corp.fabricam.com]]>. - Assign to a pilot group, sync a device, and verify with
Get-NetConnectionProfilethat 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."
- In the GPO editor expand Computer Configuration, then Windows Settings, then Security Settings, then Network List Manager Policies.
- 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.
- 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.
- Open All Networks to control whether users can change the network name, location or icon for any network.
- 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-NetConnectionProfileand withgpresult /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.
The second half of the run is the event timeline, and this is where the mechanism stops being theory.
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
- Domain-joined machines can't detect the domain profile - the definitive walkthrough of the DsGetDcName, TCP 389 and LDAP bind chain, the NetworkList registry keys, and the Windows 11 change of ownership from NLA to the Network List Manager.
- Windows Firewall overview - the three profiles, the statement that Domain cannot be set manually, and the pointer to the NetworkListManager CSP.
- NetworkListManager Policy CSP - every OMA-URI, allowed value and endpoint requirement for TLS-based network authentication.
- Firewall profile doesn't switch to Domain when you use a third-party VPN (KB4550028) - the route-timing cause and the NegativeCachePeriod and MaxNegativeCacheTtl workaround with documented defaults.
- Netlogon event ID 5719 or Group Policy event 1129 - the documented race condition between network initialisation, DC location and Group Policy, plus the wait-time policies and GpNetworkStartTimeoutPolicyValue.
- ADMX_Logon Policy CSP - SyncForegroundPolicy, its exact wording, its System > Logon location and its Winlogon registry value.
- Network List Manager policies - the Security Settings GPO path and the Unidentified Networks, Identifying Networks and All Networks options.
- NLM_NETWORK_CATEGORY and NLM_DOMAIN_TYPE - the category and domain-type numeric values.
- Network Connectivity Status Indicator overview - active and passive probing, the NlaSvc\Parameters\Internet registry path, and the confirmation that NCSI moved into the Network List Manager service on Windows 11.
- Network Location Awareness Service Provider (NLA) - what NLA is, in Microsoft's own words.
- VPNv2 CSP - the TrustedNetworkDetection node used with ConfiguredTlsAuthenticationNetworkName.
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.
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.