Will NTLM Deprecation Stop Your Business Apps? — How to Collect Audit Logs, and the Order in Which to Kill Dependencies

· · NTLM, Kerberos, Windows, Active Directory, Security, Information Systems, PowerShell

“Apparently NTLM is being retired. Are we going to be all right?” — since Microsoft announced in June 2024 that all versions of NTLM were deprecated, this question has come up more and more often. The answer is: you can find out whether you’re all right, and if you look now, you have time.

Retiring NTLM is not the kind of change where a patch lands one day and the whole company stops. It tightens a little with each new OS — and only while NTLM still works can you safely produce a list of “where in our estate we depend on NTLM”. Turning everything off and then hunting for what broke is the one order you must not use.

This article focuses on the practical procedure for producing that list and working through it. The mechanics of the protocols themselves (why NTLM is risky, why things fail to reach Kerberos) are split out into the companion article “NTLM and Kerberos Explained with Diagrams — Why Authentication Falls Back to NTLM”.

1. The Bottom Line First

  • NTLM was deprecated in June 2024. That covers all versions, including LANMAN, NTLMv1, and NTLMv2, and is a declaration that “there will be no more active feature development”. At the same time, the notice says that “using NTLM will continue to work in the next release of Windows Server and the next annual release of Windows”.1
  • Some parts have already been removed. NTLMv1 was removed in Windows 11 version 24H2 and Windows Server 2025.1
  • Retirement proceeds in three phases. Phase 1 is making usage visible and auditing it; phase 2 (second half of 2026) brings features to remove the situations where NTLM is unavoidable (IAKerb, local KDC); phase 3 disables network NTLM authentication by default in the next major release.2
  • There is only one thing to do right now: run audit mode and produce a list of “which machine, which application, against which server” is using NTLM (Section 4).
  • Investigate domain accounts starting from the domain controller. Follow event 8004 → 8003 on the member server → 8001 on the client, and you arrive at the application name (Section 4.2). But authentication with local accounts does not pass through a domain controller, so no 8004 appears. Pick that route up from 8003 on the server and 8001 on the client.3
  • Most causes come down to “names”. Hard-coded IP addresses and unregistered SPNs are the two biggest factors, and both can be fixed without rebuilding the application (Section 5).32
  • There is a way to test safely on a single machine. On Windows 11 24H2 / Windows Server 2025, NET USE \\server\share /BLOCKNTLM lets you check “does this connect without NTLM?” without changing a single policy (Section 7).4
  • In your own applications, change the places that name NTLM to Negotiate. Microsoft itself writes “do not access the NTLM security package directly” (Section 8).5

2. What “Deprecated” Actually Means

Let’s settle the terminology first. Explain this to the business while it’s still vague and you get “apparently we can’t use it any more” and “apparently we’re fine for years” circulating at the same time, and the conversation falls apart.

Summarised, the NTLM entry in Microsoft’s list of deprecated features makes three points.1

  1. All versions of NTLM, including LANMAN, NTLMv1, and NTLMv2, are no longer under active feature development and are deprecated.
  2. Using NTLM will continue to work in the next release of Windows Server and the next annual release of Windows.
  3. Calls to NTLM should be replaced by calls to Negotiate, which attempts to authenticate with Kerberos and falls back to NTLM only when necessary.

And as an update, it notes that NTLMv1 was removed in Windows 11 version 24H2 and Windows Server 2025.1

So the current position is “deprecated”, not “removed”. NTLMv1 alone has gone past deprecation and into the removal phase. If an old multifunction printer or NAS can only authenticate with NTLMv1, updating to Windows 11 24H2 breaks it there and then. This is not a future problem; it is happening now.

The other thing to keep in mind is that NTLM still has uses for which no replacement exists. Microsoft states explicitly that NTLM is, and must be, still used for Windows authentication on systems configured as members of a workgroup, and for local logon authentication on non-domain controllers.6 The local KDC planned for phase 2 is precisely the feature intended to fill that “NTLM is needed for local accounts” hole.2

3. Why It’s Going Away — Three Minutes Only

Just enough to inform the migration decision. The detailed illustrated version is left to the companion article.

In its policy setting documentation, Microsoft states plainly that NTLM and NTLMv2 authentication is vulnerable to a variety of malicious attacks, including SMB relay, man-in-the-middle attacks, and brute force attacks.7 At the root of it are the following properties, always discussed by comparison with Kerberos.8

  • No mutual authentication. With NTLM, a client cannot verify a server’s identity, nor can one server verify another server’s identity. NTLM was designed for network environments where it can be assumed that servers are genuine. Kerberos makes no such assumption. That difference is what makes relay attacks — getting credentials sent to a fake server — possible.
  • The server contacts a domain controller every time (for domain accounts). With NTLM, an application server must connect to a domain controller every time it authenticates a client with a domain account (for an account local to the server, the server consults its own account database and decides for itself).6 With Kerberos, renewable session tickets replace this pass-through authentication, and the server does not need to go to a domain controller except when PAC (privilege attribute certificate) validation is required.
  • The authentication material is the password hash itself. NTLM credentials consist of a one-way hash of the domain name, user name, and password, and the client encrypts the challenge with that hash and returns the response.5 From this follows the property that stealing the hash lets you impersonate the user without knowing the plaintext password.

The practical meaning of “no mutual authentication” is that simply trying to connect to an SMB share can hand your credentials to a fake server. Microsoft’s stated reason for providing NTLM blocking on the SMB client side is exactly this: “to prevent techniques that get NTLM requests sent to malicious servers”.4

4. Auditing — Listing Where NTLM Is Used

This is the heart of it. Microsoft’s guidance likewise states that discovering and auditing the current state of NTLM authentication traffic is necessary before implementing restriction policies.9

4.1. Enabling Audit Mode

There are three policies to set. All of them live under Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options, and no restart is required. Whether saved locally or distributed by Group Policy, they take effect the moment the setting is applied.7

That said, “no restart required” and “effective on every machine immediately” are different things. When distributing via a domain GPO, saving the GPO only updates the policy in AD/SYSVOL; each machine actually starts auditing at its next background refresh or after a gpupdate /force. Count the start of the audit period not as “the date and time the GPO was saved” but as “the date and time the setting had propagated to the target machines”. Get this wrong and only the first round of aggregation covers fewer machines, skewing your results.

Policy Applies to Value
Network security: Restrict NTLM: Audit NTLM authentication in this domain Domain controllers Enable all
Network security: Restrict NTLM: Audit Incoming NTLM Traffic All servers and clients Enable auditing for all accounts
Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers All servers and clients Audit all

The third one, “Outgoing NTLM traffic to remote servers”, has four values — Allow all / Audit all / Deny all / Not Defined — and Not Defined behaves the same as Allow all. Microsoft’s recommendation is equally clear: do not jump to “Deny all”; set “Audit all” first, review the operational log to understand which servers are receiving authentication requests, and only then build your exception list.7

Events are recorded to Event Viewer > Applications and Services Logs > Microsoft > Windows > NTLM (Microsoft-Windows-NTLM/Operational). There is no corresponding security audit event policy for this auditing, so you look at this channel rather than the Security log.7

Caution: Audit mode only records; it blocks nothing. On the other hand, in a large estate the log volume goes up sharply. If you are not using event forwarding (WEF), review the log size limit and retention period before enabling it. Microsoft’s guidance also notes that analysis can take several months depending on the complexity of the environment.3

4.2. Trace “Downstream From the Domain Controller”

There is a fixed order in which to read the events you collect. The trace path shown in Microsoft’s guidance is as follows.3

Secure Channel Name =the server to look atWorkstation Name =the client to look atClient Process NamePID 4 (SYSTEM) meansit went via SMBDomain controllerEvent 8004Member serverEvent 8003ClientEvent 8001The application at fault

Figure 1: The order in which to trace NTLM audit events

Here is what to look at in each event.3

Event Where it is recorded Key fields How to read it
8004 Domain controller Time / Secure Channel Name / User Name / Domain Name / Workstation Name The “Secure Channel Name” is the member server the client connected to. Next, look at 8003 on that server
8003 Member server Time / User Name / Domain Name / Workstation Name / PID PID 4 (SYSTEM) means it came via kernel mode (= SMB). Look at 8001 on the client named in “Workstation Name”
8001 Client Time / Target Server / Specified User / Specified Domain / Client Process Name / Client Process User ID This is where the cause is confirmed. If the “Target Server” is in neither NetBIOS nor FQDN form (= an IP address), Kerberos will not be used in the default configuration

What is especially valuable on this path is the “Target Server” and “Client Process Name” in 8001. The former tells you directly why it did not become Kerberos; the latter tells you who is to blame. Microsoft’s guidance explains that this information lets you identify that a user is connecting to a web server’s IP address rather than the NetBIOS name or FQDN with which Kerberos could have been used.3

Note that there are cases where no 8004 appears on the domain controller. When a local user account is used to connect to a file server, that authentication does not go through a domain controller.3 Do not look at the DC logs, see very little, and conclude that you are fine.

4.3. Aggregating With PowerShell

Staring at thousands of entries in the Event Viewer GUI is not realistic, so use Get-WinEvent to summarise. First, check which events are present on the machine and in what numbers.

# Aggregate NTLM/Operational events by ID (run as administrator)
Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-NTLM/Operational'
    StartTime = (Get-Date).AddDays(-7)
} -ErrorAction SilentlyContinue |
    Group-Object Id |
    Sort-Object Count -Descending |
    Select-Object Count, @{ N = 'EventId'; E = { $_.Name } }

Once you have confirmed that events are being generated, group the client-side 8001 events by “destination server × calling process”. The field layout differs per event ID, so it is safest to open one event with Format-List and check the structure before deciding on indices.

# First, inspect the contents of a single event
$sample = Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-NTLM/Operational'
    Id      = 8001
} -MaxEvents 1

$sample | Format-List TimeCreated, Id, Message
# To see the structured fields
([xml]$sample.ToXml()).Event.EventData.Data |
    Select-Object Name, '#text'

Once you know the structure, extract by the XML Name attribute and aggregate. Attribute names vary between OS versions, so looking them up by name is less brittle than positional indexing.

# Aggregate the last 7 days of 8001 by "destination x calling process"
$events = Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-NTLM/Operational'
    Id        = 8001
    StartTime = (Get-Date).AddDays(-7)
} -ErrorAction SilentlyContinue

$rows = foreach ($e in $events) {
    $data = @{}
    foreach ($d in ([xml]$e.ToXml()).Event.EventData.Data) {
        $data[$d.Name] = $d.'#text'
    }
    [pscustomobject]@{
        Time    = $e.TimeCreated
        # Pick up only the field names that actually existed, in priority order
        Target  = @('TargetName', 'TargetServer', 'ServerName') |
                  Where-Object { $data.ContainsKey($_) } |
                  ForEach-Object { $data[$_] } | Select-Object -First 1
        Process = @('ClientProcessName', 'ProcessName', 'ApplicationName') |
                  Where-Object { $data.ContainsKey($_) } |
                  ForEach-Object { $data[$_] } | Select-Object -First 1
    }
}

$rows | Group-Object Target, Process |
    Sort-Object Count -Descending |
    Select-Object Count, Name

Because field names differ between OS versions, the code lists candidates in a priority-ordered array and picks up only the ones that actually exist. If you use a partial match such as -match 'Process' here, you can also catch PID fields like ClientProcessId and end up aggregating by a PID that changes every time rather than by the executable name (and since hash table key order is undefined, which one you get is not even stable). If the Process column comes back entirely empty, that is a sign that your candidate names do not match the actual schema — add the names you confirmed in the previous step to the array.

To collect from multiple machines, running them in parallel with PowerShell Remoting is fastest (“Getting Started with PowerShell Remoting (WinRM) — Managing Multiple Windows Machines at Once”). Filtering with Get-WinEvent differs by orders of magnitude in run time depending on whether you use -FilterHashtable, and the essentials are set out in “Investigating Event Logs Practically with Get-WinEvent — Filtering Speed Determines Investigation Time”.

4.4. Looking From the Security Log Side — Is NTLMv1 Still in Use?

Separately from NTLM/Operational, there is a way to check the NTLM version from logon events in the Security log. The procedure is to search the Security log for “Authentication Package” and look at the “Detailed Authentication Information” of each event.3

Detailed Authentication Information:
    Logon Process:              NtLmSsp
    Authentication Package:     NTLM
    Transited Services:         -
    Package Name (NTLM only):   NTLM V1
    Key Length:                 128

That “Package Name (NTLM only)” tells you which sub-protocol of the NTLM family was used.3 A host showing NTLM V1 is a candidate for authentication failure if you upgrade it as-is to Windows 11 24H2 / Windows Server 2025, because NTLMv1 has been removed in those versions.1 When you run the audit, raise the priority of this one aspect in particular.

4.5. When Everything Is PID 4 (SYSTEM) and You Can’t Get Any Further

Start auditing and you will almost certainly hit this wall. For applications that communicate through the redirector, such as SMB (shared folders), the entity requesting authentication is the kernel-mode redirector, so the PID left in the event is always 4 (SYSTEM).3

Microsoft’s guidance gives this remedy.3

  1. Install a process monitoring tool on the client that is sending the NTLM credentials (the “Computer” in 8001).
  2. Filter paths by both the peer server’s computer name and its IP address. If a long capture is needed, run it in background mode.
  3. Correlate the capture with the timestamps of event 8003 on the server side. The user, path, and authentication identifier line up, and from there you can identify the calling application.

The tool is Process Monitor (ProcMon). How to apply filters and read the output is covered in “A Practical Guide to Process Monitor (ProcMon) — Pinpointing "Settings Not Applied" and "ACCESS DENIED" in 10 Minutes”.

One practical tip to add: narrow down “which machine” using the event logs alone up to this point, and then deploy ProcMon on that one machine only. Rolling ProcMon out to every machine is not realistic.

5. The Typical Patterns That Fall Back to NTLM

Once the audit has told you where, the next step is classifying the cause. Microsoft’s guidance lists four kinds of applications that use NTLM even though they theoretically support Kerberos.3

  • Applications that let you choose among various security configurations and providers
  • Applications whose SPN (service principal name) is not correctly configured
  • Applications that use IP addresses rather than DNS names, because of a misconfiguration or the vendor’s documentation
  • Applications with a legacy codebase that still contains NTLM-only parts

The Microsoft Japan support blog lists, as the representative causes of NTLM being used, server access specified by IP address, firewall restrictions on the ports Kerberos needs, unregistered SPNs, authentication to a trusted partner, and authentication in a workgroup environment.2

Recast into the shapes you actually encounter in the field, they produce the following table.

Symptom / configuration Why it becomes NTLM How to confirm Category
Connecting to a share by IP address such as \\192.168.1.10\share By default, Windows does not attempt Kerberos authentication when the host name is an IP address10 The “Target Server” in event 8001 is an IP address Fixable right away
The destination setting of a business app is an IP address Same as above. Vendor instructions often specify an IP Identify the application from “Client Process Name” in event 8001 Fixable right away
Access via a DNS alias (CNAME) or a custom name in hosts No SPN is registered for that name Check the SPN list of the relevant service account Fixed by registering an SPN
An in-house service or IIS site runs under a dedicated account No SPN registered on the service account Same as above Fixed by registering an SPN
A branch office or VPN link cannot reach a domain controller The traffic Kerberos needs does not get through, so it falls back Firewall rules and DC reachability A routing problem
A NAS, MFP, or scanner sends to a Windows share over SMB The device does not support Kerberos, or it authenticates with a local account The device’s authentication settings, and 8003 on the server side Device-dependent
Workgroup machines, share access with local accounts (both ends running new Windows) Not domain accounts, so Kerberos is not even in play No 8004 appears on the domain controller Phase 2 may solve it
Same as above, but the peer is an older Windows or third-party device Same as above, but the local KDC only works between supporting Windows systems Check the peer’s OS version / model You must act yourself (join the domain, replace, use another protocol, or make an exception)
Authentication to another company’s domain or an untrusted peer No Kerberos ticket can be issued The “Specified Domain” in event 8001 Requires a design decision
An old packaged product that lets you choose the authentication method The setting is pinned to NTLM The product’s authentication settings screen Change the setting, or ask the vendor

The items classified as “Fixable right away” and “Fixed by registering an SPN” should account for the bulk of your audit results. Clearing those alone leaves far fewer exceptions.

6. A Decision Table for Fixes

Category What to do Watch out for
Hard-coded IP address Change the destination to an FQDN. Comb through shortcuts to shared folders, drive mappings, application config files, batch files, and even Task Scheduler arguments Confirm first that name resolution definitely works. Pitfalls around network drives and UNC paths are covered in a separate article
Hard-coded IP address, but the name genuinely cannot be changed Set TryIPSPN on the client and manually register an SPN for the IP address with Setspn -s <service class>/<IP address> <account> Last resort. Register the service class the client actually requests. Services that map to HOST, such as shared folders, are covered by host/192.168.1.1, but the web needs HTTP/192.168.1.1 and SQL Server needs a different SPN including the port, such as MSSQLSvc/192.168.1.1:1433; registering only host/ will not match and it falls back to NTLM. Microsoft itself says IP addresses are transient, so they should not normally be used in SPNs, and this is manual work to be used only when a change to a DNS name is impossible. With DHCP, a static reservation is a prerequisite. The setting is needed on each client that connects10
Unregistered SPN Register an SPN under the name used for access, on the account running the service Duplicate SPN registrations break Kerberos authentication itself. Always check for existing duplicates before registering
Access via an alias (CNAME) Either register an SPN for the alias too, or standardise access on the FQDN The cause is a mismatch between “the real name” and “the name actually used”, so decide first which of the two you are standardising on
A site that cannot reach a DC Open up the traffic Kerberos needs. If the configuration can never reach a DC, phase 2’s IAKerb may be the answer IAKerb and the local KDC are due in the second half of 2026. Check the release notes for whether they will actually be available on the versions you run2
Local-account operation Sort by what the peer actually is, first. Between supporting Windows systems, phase 2’s local KDC may be the answer, but older Windows and third-party devices (NAS, MFPs, and so on) are not covered. For the latter, choose one of: join the domain, replace the device, switch to another protocol, or add an exception Do not lump everything into “it’s a local account, so we wait for phase 2”. What IAKerb solves is DC reachability, not whether local accounts or third-party devices are supported. For local logon authentication and workgroup configurations, NTLM will still be needed going forward62
NAS, MFP Ask the manufacturer about firmware support. If Kerberos support is impossible, switch to a non-SMB delivery route (SMTP, FTPS, a dedicated folder) or replace the device Devices that can only speak NTLMv1 are the top priority. They are already removed in Windows 11 24H2 / Server 20251
A product that lets you choose the authentication method Choose Negotiate/Kerberos in the settings. If you cannot, ask the vendor for their roadmap An answer of “no plans to support it” is input to your replacement plan
In-house applications Replace explicit NTLM with Negotiate (Section 8) It is not only the code that needs fixing, but also how destinations are written
Whatever remains regardless Register it on the server exception list, and count that list every year An exception is a stay of execution, not a solution. Use “is the number going down?” as your metric7

7. NTLM Blocking on SMB — The Shortest Route to Field Verification

Audit logs tell you what is being used; they do not tell you what happens if you stop it. That is where the NTLM blocking on the SMB client side, added in Windows Server 2025 and Windows 11 version 24H2, comes in.4

This feature blocks the SMB client from using NTLM authentication on outbound connections to remote machines. Microsoft says it prevents techniques that get NTLM requests sent to malicious servers and counters brute force, cracking, and Pass-the-Hash attacks, and positions NTLM blocking as necessary for switching an organisation’s authentication protocol to Kerberos. At the same time, it notes that you can enable this layer of protection without disabling NTLM completely.4

There are two prerequisites.4

  • The SMB client is Windows Server 2025 or later, or Windows 11 version 24H2 or later
  • The destination SMB server can use Kerberos (the SMB server’s own OS can be anything that supports PKU2U or Kerberos)

7.1. Test One Machine and One Connection First

Rather than distributing a policy straight away, use the fact that blocking can be specified per connection. This is the shortest route to field verification.

# Connect with NTLM forbidden for that connection only
# (if it connects, that share is fine without NTLM)
NET USE \\fileserver.corp.example.com\share /BLOCKNTLM

# The same thing can be done with a PowerShell mapping
New-SmbMapping -RemotePath \\fileserver.corp.example.com\share -BlockNTLM $true

If it connects, that route works without NTLM. If it fails, that is an NTLM dependency. You can verify “will this break in production?” one connection at a time, without changing a single policy, which makes it ideal for corroborating the audit logs.

However, this check requires a procedure. Run it without thinking and you will get false results in both directions.

$server = 'fileserver.corp.example.com'

# 1. Remove *every* mapping to that server
#    If even one other share remains, the per-server session stays alive
net use | Select-String $server              # First, see what is connected
net use \\$server\share  /delete
net use \\$server\other  /delete             # And every other share on the same server

# 2. Confirm the session really is gone (do not proceed until this is empty)
Get-SmbConnection -ServerName $server

# 3. First confirm it connects without the flag
#    (if this fails, the problem is something other than NTLM)
net use \\$server\share
net use \\$server\share /delete
Get-SmbConnection -ServerName $server        # Empty it again here too

# 4. Only then try it with /BLOCKNTLM
net use \\$server\share /BLOCKNTLM
  • Why steps 1-2 are needed: SMB sessions are per server, not per share. If an authenticated session to that server remains, the redirector reuses it rather than re-authenticating. /BLOCKNTLM only affects the authentication performed for that mapping; it does not retroactively validate an already-established session (which may have been set up with NTLM). In other words, deleting only the share under test is not enough. If another share on the same server is still connected, the test succeeds despite an NTLM dependency. Bring it down until Get-SmbConnection returns nothing. Besides your own mappings, resident applications and backup jobs can be holding sessions. If you want certainty, the fastest route is to test from a machine that has never connected to that server.
  • Why step 3 is needed: a failure to resolve the name, wrong credentials, or insufficient permissions on the share itself will also make the /BLOCKNTLM run fail. If it fails without the flag too, that is not an NTLM dependency but a different problem.

Note that all you can say from this is “NTLM was not required” — not “it authenticated with Kerberos”. The prerequisite for this feature is “an SMB server that can use Kerberos”, but the destination is also allowed to be an OS that can use PKU2U.4 So the possibility remains that the reason for success was PKU2U rather than Kerberos. With a domain-joined file server this is unlikely to matter, but when you want to pin down what actually authenticated, either run klist on the client after connecting and check whether a cifs/ ticket for that server was obtained, or check the authentication package in the logon event in the server’s Security log (Section 4.4).

7.2. Enabling It Per Machine

Once corroboration is done, move on to machine-wide blocking on pilot machines.4

# Block NTLM across the whole SMB client (administrator required)
Set-SmbClientConfiguration -BlockNTLM $true

For Group Policy, enable “Block NTLM (LM, NTLM, NTLMv2)” under Computer Configuration > Administrative Templates > Network > Lanman Workstation.4

7.3. Peers That Must Remain Go on the Exception List

Peers that genuinely need NTLM — SMB servers that are not domain-joined, for example — can be made exceptions. Enable Lanman Workstation > Block NTLM Server Exception List in Group Policy and list the IP addresses, NetBIOS names, and FQDNs to allow.4

There is no PowerShell cmdlet for creating the exception list itself, so the first time you have to configure it in the Group Policy Editor; once created, individual additions can be made by editing the registry.4

# Add entries to an existing exception list
$params = @{
  Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LanmanWorkstation"
  Name = "BlockNTLMServerExceptionList"
}
$Entries = "192.168.10.10", "corp.contoso.com", "CORP"

$CurrentValue = (Get-ItemProperty @params -ErrorAction SilentlyContinue).BlockNTLMServerExceptionList
$params["Value"] = if ($null -eq $CurrentValue) { $Entries }
                   else { $CurrentValue + $Entries }
Set-ItemProperty @params

Caution: the sample in Microsoft’s documentation has a branch for the case where the value does not yet exist that merely sets @(""), so the entries you wanted to add are silently thrown away.4 The behaviour is that the first run adds no exceptions at all and only the second run does, so the code above writes the entries directly even when the value has not been created. That said, this registry value is an area managed by Group Policy in the first place. Manage permanent exceptions on the Group Policy side, and keep this operation to emergency stopgaps. The next policy application will overwrite it.

Caution: this is a feature of the SMB client.4 NTLM over other routes (HTTP traffic from your own applications, connections to SQL Server, WinRM, and so on) is not stopped by it. Those have to be dealt with individually according to the classification in Section 5.

8. NTLM From a Developer’s Point of View — Use Negotiate

If you build Windows applications in-house, what to fix is clear. Microsoft states it explicitly.5

Applications should not access the NTLM security package directly; instead, they should use the Negotiate security package. Negotiate allows applications to take advantage of more advanced security protocols if they are supported by the systems involved in the authentication. Currently, the Negotiate security package selects between Kerberos and NTLM. Negotiate selects Kerberos unless it cannot be used by one of the systems involved in the authentication.

So the principle is to change every place that says “NTLM” to “Negotiate”. The deprecated-features entry says the same: calls to NTLM should be replaced by calls to Negotiate.1

8.1. The Common “Explicit NTLM” in .NET

// Bad: naming NTLM as the authentication type
var credential = new NetworkCredential(user, password, domain);
var cache = new CredentialCache();
cache.Add(new Uri("http://intra.example.local/"), "NTLM", credential);

var handler = new HttpClientHandler { Credentials = cache };
// Good: change only the authentication type. Pass the credentials as they were
var credential = new NetworkCredential(user, password, domain);
var cache = new CredentialCache();
cache.Add(new Uri("http://intra.example.local/"), "Negotiate", credential);

var handler = new HttpClientHandler { Credentials = cache };

What you change here is only the authentication type string. If you replace credential with CredentialCache.DefaultNetworkCredentials, you change not just the authentication protocol but the identity doing the authenticating. It will authenticate as the account running the process (a service account, or the logged-on user) rather than the account you specified, and depending on the permissions at the destination it may stop working. Keep the protocol replacement and any review of credentials as separate changes.

If, on the other hand, you actually want to authenticate as the logged-on user (integrated Windows authentication), you can write it more simply. This is the form to use when you deliberately change “who is authenticating”.

// Integrated Windows authentication (authenticate as the current logged-on user)
var handler = new HttpClientHandler
{
    UseDefaultCredentials = true,
};

Handling HttpClient itself (not wrapping it in using, creation patterns, timeout design) is covered in “Don’t Wrap HttpClient in a using Block — Practical HTTP Communication in C# Business Apps (Creation Patterns, Timeouts, Retries)”.

If you need to work with SSPI directly, System.Net.Security.NegotiateAuthentication, added in .NET 7, lets you handle authentication over Negotiate from managed code. Here too, the point is not to specify NTLM as the package name.

8.2. Look at “How Destinations Are Written” Before You Look at the Code

Even after you fix the code, if the destination is still an IP address, it will end up on NTLM anyway. By default, when the host name is an IP address, Windows does not attempt Kerberos authentication against that host and falls back to another valid protocol such as NTLM.10 Specifically, comb through the following.

  • Server names written in config files (appsettings.json, App.config, ini files)
  • The server specification in SQL Server connection strings (Data Source)
  • Places where UNC paths are assembled. Check for hard-coded IP addresses
  • Default values in installers and provisioning documents
  • Places that were rewritten to an IP during a past incident “because name resolution was flaky” and never reverted

That last item really does turn up all the time. A hard-coded IP address was the correct emergency fix at the time; today it is technical debt.

8.3. If You Are Building the Service Side

If you want your own Windows service or IIS application to accept Kerberos, you must register an SPN, under the name clients use for access, on the account that decrypts the ticket. As Microsoft itself notes, an application without a registered SPN falls back to NTLM even if it claims Kerberos support.3

Thinking of the registration target simply as “the account running the service” is where IIS trips you up. IIS Windows authentication has kernel-mode authentication enabled by default, and in that case what decrypts the Kerberos ticket is not the application pool identity but the machine account used by HTTP.sys. If you run the application pool under a dedicated domain account and therefore register the site’s HTTP SPN on that account, the SPN owner and the account that actually decrypts diverge, and rather than merely falling back to NTLM, authentication itself fails with KRB_AP_ERR_MODIFIED.

The point is to make the SPN registration target and the identity that decrypts the ticket the same. There are two workable shapes.

  • Decrypt with the machine account (leave the default): if the site is published under a host name, register that host name’s HTTP SPN on the machine account.
  • Decrypt with the application pool identity: enable useAppPoolCredentials and register the HTTP SPN on the application pool’s account.

Which you choose comes down to whether multiple servers share the same service account (if they do, standardising on the pool identity is easier to manage). Note that an SPN can only be registered on one account, so when switching, do not forget to delete the old registration. Duplicate registrations break Kerberos authentication itself.

If your design has the service impersonate the client to reach other servers (delegation), NTLM and Kerberos differ. Kerberos supports a delegation mechanism where a service connects to another service on the client’s behalf, whereas what NTLM provides goes only as far as the authorisation information needed for local impersonation.8 Implementing impersonation is covered in “Handling Windows Impersonation Tokens Correctly — Borrowing Privileges per Thread and Reverting Safely”.

9. A Roadmap for Tightening in Stages

Putting all of this together, the order of work is as follows. Every stage is conditional on being reversible.

Stage What to do How you know it’s done
0. Preparation Review event log size and retention. If you have a collection mechanism (WEF and so on), check the path Enabling auditing does not cause logs to be lost to wrap-around
1. Visibility Enable the three audit policies and collect until the business has gone round once (spanning at least one month-end close) You have a “machine × destination × process” list, and the low-frequency jobs have run
2. Classification Sort causes using the table in Section 5. Hosts showing NTLMv1 get their own top-priority bucket Every row has an owner and a category
3. Fix the names Change hard-coded IPs to FQDNs. Register SPNs The corresponding 8001 events have stopped appearing
4. Corroboration (SMB) Check one connection at a time with NET USE /BLOCKNTLM (using the procedure in Section 7.1) The main shares connect without NTLM
5. Pilot (SMB) Set-SmbClientConfiguration -BlockNTLM $true on a handful of machines, such as those in IT One close cycle passes with no impact on the business
6. Rollout (SMB) Distribute SMB NTLM blocking by Group Policy. Keep the exception list minimal The exception list is a manageable size
6b. Non-SMB Tighten the remainder — HTTP, SQL Server, WinRM, in-house applications — by taking “Outgoing NTLM traffic to remote servers” through audit → register exceptions → deny, in that order. Do the same in the same order domain-wide with “NTLM authentication in this domain” Non-SMB 8001 events have stopped appearing too
7. Ongoing Regularly count both the SMB exception list and the Restrict NTLM server exception list. Track the delivery of phase 2 features Exceptions decrease year on year

9.1. Stopping SMB Is Only Half of NTLM Remediation

Stages 4 to 6 cover SMB only. As noted in Section 7, NTLM blocking on the SMB client is a feature of the SMB client,4 and it does not affect other routes. Whatever you classified in stage 2 as “authenticating over HTTP”, “SQL Server is using NTLM”, or “WinRM is using NTLM” remains untouched even after you complete stage 6. And because it does not appear on the SMB exception list either, counting that list will not reveal it.

Stage 6b is where you tighten those. What you use is exactly the three policies you put into audit mode in Section 4. The procedure follows the same shape.

  1. Leave “Outgoing NTLM traffic to remote servers” on Audit all and enumerate the remaining destinations
  2. Register the peers you genuinely need on “Add remote server exceptions”
  3. Switch pilot machines to Deny all and wait for the business to go round once
  4. If there are no problems, roll it out

For the domain as a whole, take “NTLM authentication in this domain” through the same audit → exceptions (“Add server exceptions in this domain”) → deny sequence.11 Microsoft likewise says you should set the corresponding audit policy to the same option and evaluate the impact before choosing a deny option.11

“We blocked SMB, so NTLM remediation is complete” is wrong. If you want a completion metric, count both the SMB exception list and the Restrict NTLM server exception list.

9.2. Set the Audit Period by “One Full Business Cycle”, Not by Number of Days

The most common failure in stage 1 is how the period is decided. Declare it complete “because we collected for two weeks” and anything that did not run during those two weeks is not on the list. And whatever is not on the list breaks for the first time after you distribute the block in stage 6.

The things most easily missed are, concretely:

  • Monthly and quarterly closing processes. A month-end batch connecting to a shared folder or a database by hard-coded IP is the classic case.
  • Annual processes. Stocktakes, fiscal-year rollovers, year-end accounts.
  • Routes that are only exercised during an incident. Restore-from-backup procedures, failover to a standby server, DR drills.
  • Machines that are offline for long periods. Laptops taken off-site, machines belonging to staff on extended leave, spare machines normally left powered off.
  • Business applications used only a few times a year.

Microsoft’s own guidance notes that analysis can extend to several months depending on the complexity of the deployment.3 The realistic line to draw is one of the following.

  1. Keep the audit running until the business has gone round once. At minimum one month-end close, and ideally spanning a quarter.
  2. Enumerate low-frequency processes and deliberately execute them. If you cannot wait out the period, run the closing processes and DR procedures in a test environment and add the results to the list. The key is to interview the owners in advance and enumerate the processes that “produce no events only because they haven’t been run”.

In either case, get to a state where you can distinguish “no event was produced” from “it hasn’t run yet” before moving to the next stage.

9.3. Don’t Swing Straight to Deny

The key point here is not to swing “Outgoing NTLM traffic = Deny all” in one move. Microsoft says that setting this policy to deny can cause many NTLM authentication requests to fail and reduce productivity, so before implementing it you should check the logs with “Audit all”, analyse the servers, and build an exception list of what to exclude.7 The same warning is given for the domain-wide “NTLM authentication in this domain” policy.11

10. Summary

  • All versions of NTLM were deprecated in June 2024. This is not a change that stops anything immediately; NTLM is stated to keep working in the next release of Windows Server and the next annual release of Windows.1
  • On the other hand, NTLMv1 has already been removed (Windows 11 24H2 / Windows Server 2025). Devices that can only speak NTLMv1, and hosts recorded with NTLM V1, are your nearest deadline.1
  • Retirement has three phases: phase 1 is auditing, phase 2 (second half of 2026) is IAKerb and the local KDC, and phase 3 is disabling by default.2
  • Auditing means putting three policies into audit mode and collecting Microsoft-Windows-NTLM/Operational. For domain accounts, follow 8004 on the DC → 8003 on the member server → 8001 on the client, which finally gets you to the application name. Authentication with local accounts produces no 8004, so pick that up from the server and client events.37
  • Traffic via SMB always shows PID 4 (SYSTEM). Narrow down to the machine with the event logs, then chase that one machine with ProcMon.3
  • Most causes come down to “names”. Simply clearing hard-coded IP addresses and unregistered SPNs greatly reduces the remaining exceptions.32
  • NET USE \\server\share /BLOCKNTLM is the safest way to corroborate, one connection at a time, without changing a policy.4
  • In your own applications, replace explicit NTLM with Negotiate and standardise destination names on FQDNs.5
  • An exception list is a stay of execution, not a solution. Use “is the count going down year on year?” as your metric.

KomuraSoft LLC handles inventories of NTLM dependencies, modification of business applications for migration to a Kerberos-based estate, and investigation of authentication-related defects.

References

  1. Microsoft Learn, Deprecated features in the Windows client. On all versions of NTLM, including LANMAN, NTLMv1, and NTLMv2, being outside active feature development and deprecated; on using NTLM continuing to work in the next release of Windows Server and the next annual release of Windows; on calls to NTLM needing to be replaced by calls to Negotiate, which attempts to authenticate with Kerberos and falls back to NTLM only when necessary; on the deprecation announcement dating from June 2024; and on the November 2024 update stating that NTLMv1 has been removed from Windows 11 version 24H2 and Windows Server 2025. Also on deprecated and removed being distinct stages, with deprecated features not being actively developed and possibly removed in a future update.  2 3 4 5 6 7 8 9

  2. Microsoft Japan Windows Technology Support Blog, NTLM の廃止に向けた対応について. On NTLM retirement proceeding in three phases (phase 1 = making usage visible and auditing it; phase 2 = features for NTLM-dependent scenarios, planned for the second half of 2026; phase 3 = disabling network NTLM authentication by default in the next major release); on the three Group Policy settings to configure for auditing (audit NTLM authentication in this domain, audit incoming NTLM traffic, and outgoing NTLM traffic to remote servers = audit all) and checking the NTLM/Operational log; on considering IAKERB and the local KDC when migrating to Kerberos, with the local KDC due in the second half of 2026; on using Negotiate in applications; and on the representative causes of NTLM usage being server access specified by IP address, firewall restrictions on the ports Kerberos needs, unregistered SPNs, authentication to trusted partners, and authentication in workgroup environments.  2 3 4 5 6 7 8

  3. Microsoft Learn, Viewing events for assessing NTLM usage. On being able to tell NTLM V1 from V2 by searching the Security log’s logon events for “Authentication Package” and looking at “Package Name (NTLM only)” under “Detailed Authentication Information”; on analysis potentially taking several months depending on deployment complexity; on the four categories of application that use NTLM even though they theoretically support Kerberos (applications that let you choose the security configuration or provider, applications whose SPN is not correctly configured, applications that use IP addresses rather than DNS names because of misconfiguration or vendor documentation, and applications with NTLM-only parts in a legacy codebase); on the three audit policy settings and their corresponding event IDs; on the trace procedure from event 8004 on the domain controller (time, secure channel name, user name, domain name, workstation name) to event 8003 on the member server (time, user name, domain name, workstation name, PID) and on to event 8001 on the client (time, target server, specified user, specified domain, client process name, client process user identity); on Kerberos not being used if the target server is in neither NetBIOS nor FQDN form; on event 8004 sometimes not being generated on the domain controller when a local user account connects to a file server; and on applications that communicate through the redirector, such as SMB, always showing PID 4 (SYSTEM), so that Process Monitor is needed to identify the calling process on the client.  2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

  4. Microsoft Learn, Block NTLM connections on SMB in Windows Server 2025. On the SMB client being able to block NTLM authentication on outbound remote connections; on this preventing techniques that get NTLM requests sent to malicious servers and countering brute force, cracking, and Pass-the-Hash attacks; on NTLM blocking being necessary for switching an organisation’s authentication protocol to Kerberos while it is also possible to enable just this layer of protection without disabling NTLM entirely; on the prerequisites being an SMB client on Windows Server 2025 or later or Windows 11 version 24H2 or later, and an SMB server that can use Kerberos; on NTLM blocking being a feature of the SMB client with the destination SMB server allowed to be any OS that supports PKU2U or Kerberos; on enabling “Block NTLM (LM, NTLM, NTLMv2)” under “Computer Configuration > Administrative Templates > Network > Lanman Workstation” in Group Policy; on using Set-SmbClientConfiguration -BlockNTLM $true in PowerShell; on the “Block NTLM Server Exception List” policy taking IP addresses, NetBIOS names, and FQDNs, with no corresponding PowerShell cmdlet so the first configuration must be made in the Group Policy Editor and subsequent exceptions can be added individually via the BlockNTLMServerExceptionList registry value; and on NET USE \\server\share /BLOCKNTLM and New-SmbMapping -RemotePath \\server\share -BlockNTLM $true allowing NTLM to be blocked per drive mapping.  2 3 4 5 6 7 8 9 10 11 12 13 14

  5. Microsoft Learn, Microsoft NTLM. On NTLM credentials consisting of a one-way hash of the domain name, user name, and password obtained at interactive logon; on authenticating without sending the password over the wire by means of an encrypted challenge/response; on the steps of non-interactive authentication (the client sends the user name in plaintext, the server generates and sends an 8-byte random number as the challenge, the client encrypts the challenge with the password hash and returns the response, the server sends the user name, challenge, and response to a domain controller, and the domain controller performs the same computation with the hash retrieved from the SAM database and compares); and on applications not accessing the NTLM security package directly but using the Negotiate security package, which selects between Kerberos and NTLM and selects Kerberos unless one of the systems involved in the authentication cannot use it.  2 3 4

  6. Microsoft Learn, NTLM overview in Windows Server. On NTLM authentication being a family of authentication protocols contained in Msv1_0.dll (LAN Manager versions 1 and 2, NTLM versions 1 and 2); on it authenticating users and computers by a challenge/response mechanism; on a resource server needing, each time it requires a new access token, to query the authentication service on a domain controller for a domain account or to consult its local account database for a local account; on NTLM still being used and needing to be used for Windows authentication on systems configured as members of a workgroup and for local logon authentication on non-domain controllers; on Kerberos version 5 being the preferred authentication method in Active Directory environments; and on reducing NTLM usage requiring both an understanding of deployed applications’ requirements and configuration steps to use other protocols.  2 3

  7. Microsoft Learn, Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers. On the four values Allow all, Audit all, Deny all, and Not Defined, with Not Defined behaving the same as Allow all; on the recommended procedure of selecting “Audit all” first, reviewing the operational log, and only then building a server exception list; on the setting’s location being “Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options”; on no restart being required and the setting taking effect when saved, whether locally or distributed by Group Policy; on audit and block events being recorded in the operational log under “Applications and Services Logs\Microsoft\Windows\NTLM”, with no security audit event policy existing to surface this output; on NTLM and NTLMv2 authentication being vulnerable to malicious attacks including SMB relay, man-in-the-middle, and brute force; and on setting it to deny potentially causing many NTLM authentication requests to fail and reducing productivity, so that impact should be assessed with auditing and an exception list built beforehand.  2 3 4 5 6 7

  8. Microsoft Learn, Kerberos authentication overview in Windows Server. On the KDC running on a domain controller and using the Active Directory Domain Services database as its security account database; on Kerberos supporting delegation by services (a mechanism for connecting to other services on the client’s behalf) while what NTLM and Kerberos provide is the authorisation information a service needs to impersonate a client locally; on pre-Kerberos NTLM authentication requiring an application server to connect to a domain controller each time it authenticated a client or service, whereas with Kerberos renewable session tickets replace pass-through authentication and the server does not need to go to a domain controller except when PAC validation is required; and on Kerberos allowing either end of a connection to verify the other’s identity, whereas NTLM allows neither a client to verify a server nor one server to verify another, having been designed for environments where servers can be assumed genuine.  2

  9. Microsoft Learn, Assessing NTLM usage. On the need to discover and audit the current state of NTLM authentication traffic before implementing policies and practices to use improved authentication protocols such as Kerberos; on the three points at which NTLM usage should be captured (outgoing traffic from domain controllers within the domain, incoming traffic to remote servers, and incoming traffic from clients to remote servers); and on understanding the environment being an iterative task. 

  10. Microsoft Learn, Configuring Kerberos for IP Address. On being able, from Windows 10 version 1507 and Windows Server 2016 onwards, to make the Kerberos client support IPv4/IPv6 host names in SPNs; on Windows by default not attempting Kerberos authentication against a host whose host name is an IP address, falling back to another valid authentication protocol such as NTLM; on applications hard-coding IP addresses therefore falling back to NTLM and potentially causing compatibility problems in environments that are disabling NTLM; on the feature to use IP addresses as SPN host names having been introduced to reduce that impact, enabled by setting the client-side registry value TryIPSPN (REG_DWORD, not present by default) under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters to 1, with the setting required on each client that needs to access Kerberos-protected resources by IP address; and on IP addresses being transient and liable to cause conflicts and authentication failures as leases expire and renew, so they should not normally be used in place of host names, with IP-address-based SPN registration being manual work to be used only when switching to a DNS-based host name is impossible, registered with Setspn -s <service>/<ip.address> <domain-user-account> — and since an SPN can only be registered on one account at a time in Active Directory, static reservation of the IP address is recommended when DHCP is in use.  2 3

  11. Microsoft Learn, Network security: Restrict NTLM: NTLM authentication in this domain. On the values Disable, Deny for domain accounts to domain servers, Deny for domain accounts, Deny for domain servers, Deny all, and Not Defined; on this policy applying only to domain controllers and not affecting interactive logon to domain controllers; on denied requests receiving an NTLM-blocked error, with servers on the exception list of the “Add server exceptions in this domain” policy excluded; and on the need, before choosing a deny option, to set the corresponding audit policy to the same option and evaluate the impact using the operational log.  2 3

Recent articles sharing the same tags. Deepen your understanding with closely related topics.

These topic pages place the article in a broader service and decision context.

This article connects naturally to the following service pages.

Frequently Asked Questions

Common questions about the topic of this article.

When NTLM is retired, when will our business grind to a halt?
A "deprecated" announcement on its own stops nothing. Microsoft deprecated all versions of NTLM in June 2024, but the accompanying guidance said that NTLM will continue to work in the next release of Windows Server and the next annual release of Windows. The concrete change that has already broken things is the removal of NTLMv1 in Windows 11 version 24H2 and Windows Server 2025. There is a published plan to disable network NTLM by default in a future release, but even then it is stated that it can be re-enabled by policy. In other words this is not the kind of change where the whole company stops one day; it is the kind that tightens a little with each new OS. That is precisely why the only realistic preparation is to inventory your dependencies with audit logs while NTLM still works, rather than investigating after something has broken.
How do I produce a list of the places where NTLM is used?
Put the "Network security: Restrict NTLM" family of Group Policy settings into audit mode and collect the NTLM/Operational log. Set "Audit NTLM authentication in this domain" on domain controllers, and "Audit Incoming NTLM Traffic" plus "Outgoing NTLM traffic to remote servers = Audit all" on servers and clients, and events are recorded under Applications and Services Logs > Microsoft > Windows > NTLM in Event Viewer. For domain-account authentication, the order to follow is: identify the user and the destination server (Secure Channel Name) from event 8004 on the domain controller, look at the process ID in event 8003 on that server, and finally pin down "which application, against which server name" with event 8001 on the client. Event 8001 carries the target server name and the client process name, so once you get that far you know which application is at fault. Note that authentication with local accounts does not go through a domain controller, so no 8004 appears. Routes where a workgroup machine or a local account on a file server connects to a share have to be picked up from 8003 on the server and 8001 on the client. Do not look only at the domain controller logs and conclude "we hardly use it".
I turned on auditing and the events all show PID 4 (SYSTEM). I can't tell which application it is.
That's because the traffic goes via SMB (shared folders). SMB authentication is performed by the kernel-mode redirector, so the calling application is hidden behind the SMB packets and the PID left in the event is always 4 (SYSTEM). Microsoft's guidance calls out this case explicitly and recommends running Process Monitor (ProcMon) on the client where the events appear, filtering paths by the peer server's computer name and IP address, and correlating with the timestamps of event 8003 on the server side to identify the calling process. In practice, the fast route is to narrow down "which machine" with the event logs first, and then chase only that machine with ProcMon.
Why does an application that supposedly supports Kerberos fall back to NTLM?
Almost always it's a naming problem. Microsoft's guidance lists four kinds of applications that use NTLM even though they theoretically support Kerberos: applications that let you choose the security configuration or provider; applications whose SPN (service principal name) is not registered correctly; applications that connect by IP address rather than DNS name because of a misconfiguration or the vendor's documentation; and applications with a legacy codebase that still contains NTLM-only parts. If the "Target Server" in event 8001 is in neither NetBIOS nor FQDN form (that is, it's an IP address), Kerberos will not be used in the default configuration. The first two moves are to change hard-coded IP addresses to FQDNs, and to register an SPN for the alias if access uses one. There is also a way to configure TryIPSPN on clients and manually register an SPN for the IP address, for cases where the name genuinely cannot be changed — but Microsoft itself says this should be limited to situations where switching to a DNS name is impossible, so treat it strictly as a last resort.
What should we fix in the Windows applications we build ourselves?
Replace anywhere that names NTLM as the authentication package with Negotiate. Microsoft states explicitly that "applications should not access the NTLM security package directly; they should use the Negotiate package instead". Negotiate selects either Kerberos or NTLM, and selects Kerberos unless one of the systems involved in the authentication cannot use it. In .NET, the typical fix is to change the authentication type passed to CredentialCache.Add from "NTLM" to "Negotiate" (the authentication type is specified on CredentialCache.Add, not on the NetworkCredential constructor). Alongside that, you also need to specify destinations by FQDN rather than by IP address or an alias written into hosts, and — if you want your own service to accept Kerberos — to register an SPN on that service account.

Author Profile

Profile page for the article author.

Go Komura

Representative of KomuraSoft LLC

Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.

Back to the Blog