Windows Server 2025 did not switch NTLM off. Microsoft removed NTLMv1 from the Windows client and deprecated the rest, yet a fully patched Windows Server 2025 NTLM setup still answers NTLMv2 by default. In our lab it even accepted an NTLMv1 logon from a Linux client until one policy changed. The Kerberos change that actually breaks logons is RC4: tickets now depend on how each account is configured, and an RC4-only client gets no ticket at all.
You’ll follow NTLM from audit to block on a single domain controller: the GPO that turns on auditing, events 8001 to 8004 and the newer 4020 to 4033 records, the deny settings that disable NTLM, the exception list, and how to enable NTLM again cleanly. The Kerberos half tests encryption types with an RC4-only service account and a Linux kinit client. Everything below was run on a Windows Server 2025 domain controller with the October 2026 cumulative update and an Ubuntu 26.04 client in October 2026.
Windows Server 2025 NTLM: v1 is gone, v2 is not
Microsoft’s removed and deprecated features list says NTLMv1 is removed and that NTLMv2 keeps working but is deprecated. People read that as “the DC refuses NTLMv1”, and it does not, because a server that no longer sends NTLMv1 can still accept it from something else. The table sets each change next to what a freshly promoted DC with no hardening did in the lab.
| Area | Server 2025 behaviour | What the lab showed |
|---|---|---|
| NTLMv1 | Removed from Windows as a client | The DC still accepted an NTLMv1 logon from Samba’s smbclient until LAN Manager level 5 was set |
| NTLMv2 | Deprecated, enabled by default | Worked in both directions with no policy set |
| NTLM logging | Enhanced events 4020 to 4033 on by default | Events were already in the log before any GPO existed |
| Kerberos RC4 | No RC4 TGTs; RC4 service tickets only for accounts set to allow it | RC4-only kinit refused; RC4 ticket issued for an account with msDS-SupportedEncryptionTypes = 4 |
| Local KDC | New LocalKdc service, pre-release | Present, Stopped, start type Manual |
Your order of work follows from that table. Audit first, because the deny settings fail closed and the events are the only list of what still uses NTLM. Then block in layers, starting with pass-through to member servers. Set the LAN Manager level on day one, since it costs you nothing that the logs haven’t already flagged.
One DC and one Linux box are enough
Two VMs produce every event in this guide except 8003, which needs a Windows member server. The Linux machine plays two roles. It is the Kerberos and SMB client, and it is also a Samba member server, so the DC has NTLM pass-through traffic to audit.
dc01at 10.0.1.10: Windows Server 2025 Datacenter, AD DS and DNS- Forest
corp.example.com, NetBIOS nameCORP, functional level Windows2025 client01at 10.0.1.20: Ubuntu 26.04 withkrb5-user,smbclientand Samba- Test accounts
kenneth,svc-modernandsvc-legacy
The diagram shows the four paths the tests take. Paths 1 and 2 are NTLM that a member server forwards, path 3 is NTLM aimed at the DC itself, and path 4 is Kerberos, which none of the Restrict NTLM settings touch:

Keep those paths apart in your head. Deny in this domain closes path 2, Incoming NTLM traffic closes path 3, and LAN Manager level 5 only refuses NTLMv1 on path 3. The outgoing deny later in the guide covers a fifth path the diagram leaves out: the DC itself connecting to another server.
If you still need the DC, install Active Directory Domain Services on Windows Server or promote the forest with PowerShell. Our Proxmox clone came from the template in this Windows Server template guide, patched to the October 2026 update before promotion. client01 is built further down in this section as a Samba member server, which is a different join from the SSSD one in the Ubuntu and Debian AD join guide.
Create the test accounts on the DC. svc-legacy gets msDS-SupportedEncryptionTypes set to 4, which means RC4 only, while svc-modern stays at the default so you can compare the two later.
$pw = Read-Host -AsSecureString 'Password'
New-ADUser -Name kenneth -SamAccountName kenneth -UserPrincipalName [email protected] -AccountPassword $pw -Enabled $true -PasswordNeverExpires $true
New-ADUser -Name svc-legacy -SamAccountName svc-legacy -AccountPassword $pw -Enabled $true -PasswordNeverExpires $true -ServicePrincipalNames 'HTTP/legacy.corp.example.com'
New-ADUser -Name svc-modern -SamAccountName svc-modern -AccountPassword $pw -Enabled $true -PasswordNeverExpires $true -ServicePrincipalNames 'HTTP/modern.corp.example.com'
Set-ADUser svc-legacy -Replace @{'msDS-SupportedEncryptionTypes'=4}
Get-ADUser -Filter 'Name -like "svc-*" -or Name -eq "kenneth"' -Properties msDS-SupportedEncryptionTypes,servicePrincipalName | Format-Table Name,msDS-SupportedEncryptionTypes,servicePrincipalName -AutoSize
Only svc-legacy shows a value. An empty column on svc-modern means the KDC falls back to the domain default, which is AES on a patched DC.
Name msDS-SupportedEncryptionTypes servicePrincipalName
---- ----------------------------- --------------------
svc-legacy 4 {HTTP/legacy.corp.example.com}
svc-modern {HTTP/modern.corp.example.com}
kenneth {}
Keep svc-legacy around after the lab. Its exact configuration exists in many real domains, usually set years ago for an appliance nobody remembers.
Now prepare client01. It needs the Kerberos client, smbclient and Samba with winbind, because it acts as both the test client and a member server that forwards NTLM to the DC:
sudo apt update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y krb5-user smbclient samba winbind libnss-winbind
Our lab network had no DNS delegation for corp.example.com, so both names went into /etc/hosts. Skip this if your client already resolves the domain through the DC.
echo "10.0.1.10 dc01.corp.example.com dc01" | sudo tee -a /etc/hosts
echo "10.0.1.20 client01.corp.example.com" | sudo tee -a /etc/hosts
Point MIT Kerberos at the DC by opening the client configuration:
sudo vim /etc/krb5.conf
Replace the file with this one, which is exactly what we used. dns_lookup_kdc = false and the explicit kdc line keep the test independent of SRV records. A host that is fully joined, as in our Rocky Linux and RHEL AD join guide, gets an equivalent file from realmd.
[libdefaults]
default_realm = CORP.EXAMPLE.COM
dns_lookup_kdc = false
rdns = false
[realms]
CORP.EXAMPLE.COM = {
kdc = dc01.corp.example.com
admin_server = dc01.corp.example.com
}
[domain_realm]
.corp.example.com = CORP.EXAMPLE.COM
corp.example.com = CORP.EXAMPLE.COM
Next comes the Samba member configuration. Back up the packaged file and open a new one:
sudo mv /etc/samba/smb.conf /etc/samba/smb.conf.orig
sudo vim /etc/samba/smb.conf
This is the full file from the lab. security = ads makes smbd a domain member, so it hands every NTLM logon for a CORP account to the DC over Netlogon, which is the pass-through traffic we want to audit:
[global]
workgroup = CORP
realm = CORP.EXAMPLE.COM
security = ads
netbios name = CLIENT01
idmap config * : backend = tdb
idmap config * : range = 3000-7999
idmap config CORP : backend = rid
idmap config CORP : range = 10000-999999
winbind use default domain = yes
[share]
path = /srv/share
read only = no
Create the share directory, join the domain with a domain admin and restart the Samba services:
sudo mkdir -p /srv/share
sudo chmod 1777 /srv/share
sudo net ads join -S dc01.corp.example.com -U Administrator
sudo systemctl restart smbd nmbd winbind
The join printed two harmless complaints in our lab, both caused by the missing DNS delegation, and then confirmed the join:
get_kdc_ip_string: get_kdc_list fail NT_STATUS_NO_LOGON_SERVERS
DNS update failed: NT_STATUS_UNSUCCESSFUL
Using short domain name -- CORP
Joined 'CLIENT01' to dns domain 'corp.example.com'
Give winbind a few seconds after the restart; queried immediately, ours answered WBC_ERR_WINBIND_NOT_AVAILABLE. Then list domain users through it:
wbinfo -u
Seeing the three test accounts means the member can look up the domain, so NTLM logons to its share will reach the DC:
administrator
guest
cloudbase-init
krbtgt
kenneth
svc-legacy
svc-modern
The cloudbase-init account comes from the Proxmox template’s provisioning agent, so yours will not have it. If wbinfo -u returns nothing at all, winbind cannot reach the DC, and every member-side test later would then fail because of the join rather than because of policy. Fix that first, since a broken join and an NTLM block print different errors and you want to see only the second kind.
Auditing comes before blocking
Three Security Options settings produce the audit events, and none of them blocks anything. In the Group Policy Management Editor you’ll find them under Computer Configuration, Policies, Windows Settings, Security Settings, Local Policies, Security Options, each named “Network security: Restrict NTLM: …”. Each one is stored as a plain registry value on the target machine.
- Restrict NTLM: Audit NTLM authentication in this domain = Enable all
- Restrict NTLM: Audit Incoming NTLM Traffic = Enable auditing for all accounts
- Restrict NTLM: Outgoing NTLM traffic to remote servers = Audit all
We created one GPO, linked it to the Domain Controllers OU and wrote the three values with Set-GPRegistryValue, so every later step is a one-line change you can repeat. Writing them this way has a side effect. GPMC shows them under Extra Registry Settings rather than Security Options, and removing one later does not clean it off the DC, which the rollback section proves.
$gpo = New-GPO -Name 'NTLM Audit - Domain Controllers'
New-GPLink -Name $gpo.DisplayName -Target 'OU=Domain Controllers,DC=corp,DC=example,DC=com'
Set-GPRegistryValue -Name $gpo.DisplayName -Key 'HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters' -ValueName AuditNTLMInDomain -Type DWord -Value 7
Set-GPRegistryValue -Name $gpo.DisplayName -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ValueName AuditReceivingNTLMTraffic -Type DWord -Value 2
Set-GPRegistryValue -Name $gpo.DisplayName -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ValueName RestrictSendingNTLMTraffic -Type DWord -Value 1
Apply it on the DC and confirm the three values reached the registry. A GPO that never applied looks exactly like a quiet network, so do not skip the check.
gpupdate /target:computer /force
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters | Select-Object AuditNTLMInDomain | Format-List
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 | Select-Object AuditReceivingNTLMTraffic,RestrictSendingNTLMTraffic | Format-List
Values 7, 2 and 1 match Enable all, all accounts and Audit all.
Computer Policy update has completed successfully.
AuditNTLMInDomain : 7
AuditReceivingNTLMTraffic : 2
RestrictSendingNTLMTraffic : 1
How long should the audit run before you block? Long enough to cover a full business cycle in production, including month-end jobs, backups and quarterly scripts. A few minutes did the job in the lab only because we generated the traffic on purpose.
Each NTLM event names a direction
Every 800x event answers one question: which side of the conversation is this machine on? To get traffic, force NTLM from the Linux client. --use-kerberos=off makes smbclient skip Kerberos even when a ticket would work.
smbclient //dc01.corp.example.com/NETLOGON --use-kerberos=off -U 'CORP\kenneth' -c 'ls'
smbclient //client01/share --use-kerberos=off -U 'CORP\kenneth' -c 'ls'
The second command hits the Samba share on client01. Samba cannot check a domain password itself, so it forwards the challenge to the DC over the Netlogon secure channel, and that forwarded request is what event 8004 records. Read the log on the DC:
Get-WinEvent -LogName Microsoft-Windows-NTLM/Operational | Sort-Object TimeCreated | Format-List TimeCreated,Id,LevelDisplayName,Message
The pass-through produced this pair. Look at the secure channel name, because that is the server the user was really trying to reach, and you will put the same name on the exception list later.
TimeCreated : 10/30/2026 5:52:53 PM
Id : 8004
LevelDisplayName : Information
Message : Domain Controller Blocked Audit: Audit NTLM authentication to this domain controller.
Secure Channel name: CLIENT01
User name: kenneth
Domain name: CORP
Workstation name: \\CLIENT01
Secure Channel type: 2
TimeCreated : 10/30/2026 5:52:53 PM
Id : 4032
LevelDisplayName : Information
Message : The DC DC01 processed a forwarded NTLM authentication request originating from this domain.
...
NTLM Security:
NTLM Version: NTLMv2
Service Binding: cifs/client01
Mic Status: MIC Protected
Status: 0x0
Status Message: STATUS_SUCCESS
The 4032 is the enhanced record from the NTLM auditing update. Microsoft’s NTLM auditing enhancements article lists the full set. It carries fields the old 8004 never had, and these are the ones worth reading first:
- NTLM Version: v1 here means a client to fix today
- Mic Status: Unprotected means no message integrity
- Service Binding: the SPN the client was aiming for
- Reason ID on 4020: why Kerberos was skipped
For outgoing traffic we ran net use \\10.0.1.20\share on the DC. That gave an 8001 and a 4020 with a reason code, which is the most useful field in the whole log:
Id : 4020
LevelDisplayName : Information
Message : This machine attempted to authenticate to a remote resource via NTLM.
...
Target Information:
Target Machine: client01
Target Resource: cifs/10.0.1.20
Target IP: 10.0.1.20
NTLM Usage:
Reason ID: 7
Reason: The target name contains an IP address.
Reason 7 gives you the fix before you block anything. A script or mapped drive connects by IP address, Kerberos has no service principal for an IP, and so Windows fell back to NTLM. Change that path to the host name and the NTLM use disappears from the log. Every event the lab produced maps to one setting:
| Event | Logged on | Produced by | Lab trigger |
|---|---|---|---|
| 8001 / 4001 | The client (here the DC) | Outgoing NTLM traffic to remote servers | net use to an IP |
| 8002 / 4002 | The server receiving NTLM | Audit Incoming NTLM Traffic / Incoming NTLM traffic | smbclient to the DC’s NETLOGON share |
| 8003 / 4003 | A Windows member server | Incoming NTLM traffic, domain accounts, on that member | Not produced: no Windows member in this lab |
| 8004 / 4004 | The DC | Audit / NTLM authentication in this domain | smbclient to the Samba member |
| 4020, 4022, 4032 | Client, server, DC | Enhanced logging, on by default | Every NTLM logon above |
| 4021, 4023 | Client, server | Same, Warning level | NTLMv1 or no channel binding |
| 4030 to 4033 | The DC | Enhanced domain-wide logging; 4031 and 4033 are the Warnings | 4032 for every pass-through above |
Deny in this domain stops pass-through, not logons to the DC
Restrict NTLM: NTLM authentication in this domain = Deny all is the setting most guides call “disable NTLM”, and it does less than the name suggests. It stops the DC from validating NTLM that a member server forwards to it. In our lab it did not stop NTLM logons whose target was the DC itself. Set it in the same GPO:
Set-GPRegistryValue -Name 'NTLM Audit - Domain Controllers' -Key 'HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters' -ValueName RestrictNTLMInDomain -Type DWord -Value 7
gpupdate /target:computer /force
Now run the same two smbclient commands from client01. The member server is refused, while the DC’s own share still opens over NTLM (the rc= lines are exit codes we echoed after each call).
session setup failed: NT_STATUS_NTLM_BLOCKED
rc=1
. D 0 Fri Oct 30 17:43:36 2026
.. D 0 Fri Oct 30 17:46:01 2026
16511487 blocks of size 4096. 12127475 blocks available
rc=0
On the DC, the blocked attempt shows up as a 4004 Warning. Its matching 4032 carries status 0xC0000418, “The authentication failed since NTLM was blocked.” To close the DC itself, add Restrict NTLM: Incoming NTLM traffic = Deny all accounts, which is RestrictReceivingNTLMTraffic = 2.
Set-GPRegistryValue -Name 'NTLM Audit - Domain Controllers' -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ValueName RestrictReceivingNTLMTraffic -Type DWord -Value 2
gpupdate /target:computer /force
Test both protocols against the DC with a Kerberos ticket already in the cache from kinit [email protected]. The first call forces NTLM, the second forces Kerberos:
smbclient //dc01.corp.example.com/NETLOGON --use-kerberos=off -U 'CORP\kenneth' -c 'ls'
smbclient //dc01.corp.example.com/NETLOGON --use-kerberos=required -c 'ls' | head -2
NTLM to the DC now fails with NT_STATUS_NOT_SUPPORTED and the DC logs a 4002 Warning, while the Kerberos call still lists the share (again with our echoed exit codes):
session setup failed: NT_STATUS_NOT_SUPPORTED
rc=1
. D 0 Fri Oct 30 17:43:36 2026
.. D 0 Fri Oct 30 17:46:01 2026
rc=0
Before you set Incoming = Deny all on a DC you manage remotely, check what reaches it without Kerberos:
- admin tools that connect by IP address
- non-domain jump hosts and monitoring probes
- backup agents that log on with a local account
We kept a key-based SSH session to the DC open the whole time, because public-key SSH never goes through NTLM. Your equivalent is the hypervisor or iLO console, and you should have it open before the GPO applies.
Exceptions take server names
Restrict NTLM: Add server exceptions in this domain lists servers the DC still validates NTLM for while Deny all is on. It wants the name from the 8004 event’s secure channel field, not an IP address. The value is a multi-string, so several servers can share one entry.
Set-GPRegistryValue -Name 'NTLM Audit - Domain Controllers' -Key 'HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters' -ValueName DCAllowedNTLMServers -Type MultiString -Value 'CLIENT01'
gpupdate /target:computer /force
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters | Select-Object RestrictNTLMInDomain,DCAllowedNTLMServers | Format-List
Deny all is still 7, and CLIENT01 is the one way through for your users. Every other member server is still refused, so you can grant a single legacy box its exception without reopening NTLM for the whole domain.
RestrictNTLMInDomain : 7
DCAllowedNTLMServers : {CLIENT01}
The smbclient test against //client01/share succeeded again, and the DC logged only a 4032 with STATUS_SUCCESS, with no 4004 and no 8004. An exception goes quiet in the audit log, so you won’t see it again unless you look for it. Keep the list short and write down why each name is on it.
Outgoing deny returns error 1937
Restrict NTLM: Outgoing NTLM traffic to remote servers = Deny all stops this machine from sending NTLM anywhere. On a DC that mostly hits admin habits, such as a net use to an IP or a script that reaches a NAS by address. We set RestrictSendingNTLMTraffic to 2 and repeated the drive mapping.
net use \\10.0.1.20\share /user:CORP\kenneth *
The mapping fails at once, and the NTLM log gets a 4001 Warning naming cifs/10.0.1.20 as the target.
System error 1937 has occurred.
Authentication failed because NTLM authentication has been disabled.
Network security: Restrict NTLM: Add remote server exceptions for NTLM authentication is the matching allow list on the client side. Microsoft’s policy page asks for the NetBIOS server names the applications use, with * as a wildcard, while the 4001 event itself suggests listing cifs/10.0.1.20. We did not test that list, so verify whichever form you use with a fresh 4001 before you rely on it.
Removing a GPO value does not enable NTLM again
The obvious rollback, deleting the deny value from the GPO, leaves NTLM blocked. These values sit outside the Policies registry branch, so Group Policy writes them and never removes them, a behaviour usually called tattooing. We tested it on the outgoing setting:
Remove-GPRegistryValue -Name 'NTLM Audit - Domain Controllers' -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ValueName RestrictSendingNTLMTraffic
gpupdate /target:computer /force
"after Remove-GPRegistryValue: RestrictSendingNTLMTraffic = " + (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0).RestrictSendingNTLMTraffic
The value stayed at 2, so the DC kept refusing outgoing NTLM after the GPO no longer mentioned it.
after Remove-GPRegistryValue: RestrictSendingNTLMTraffic = 2
To enable NTLM again, set each deny value to its allow state in the GPO and let that apply. Zero means Disable or Allow all for all three of them:
RestrictNTLMInDomain= 0 for pass-throughRestrictReceivingNTLMTraffic= 0 for logons to the DCRestrictSendingNTLMTraffic= 0 for outgoing NTLM
The same three lines in PowerShell:
$g = 'NTLM Audit - Domain Controllers'
Set-GPRegistryValue -Name $g -Key 'HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters' -ValueName RestrictNTLMInDomain -Type DWord -Value 0
Set-GPRegistryValue -Name $g -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ValueName RestrictReceivingNTLMTraffic -Type DWord -Value 0
Set-GPRegistryValue -Name $g -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0' -ValueName RestrictSendingNTLMTraffic -Type DWord -Value 0
gpupdate /target:computer /force
After that, net use to the IP completed and the NTLM smbclient test against the DC listed the share again. If you manage these in the Security Options editor instead, we would still set Allow all or Disable explicitly rather than rely on removing the setting. We did not test that path.
NTLMv1 still works until LAN Manager level 5
“NTLMv1 is removed” describes what Windows sends, not what a DC accepts from Samba, old printers or appliances. Can a patched DC still take an NTLMv1 response? Samba will send one when told to, so we tried it against the DC with no LAN Manager policy set.
smbclient //dc01.corp.example.com/NETLOGON --use-kerberos=off --option='client ntlmv2 auth=no' -U 'CORP\kenneth' -c 'ls'
The share listed, and the DC recorded the logon as NTLMv1 with a Warning, no MIC and a success status that you would never notice without the enhanced log:
Id : 4023
LevelDisplayName : Warning
Message : A remote client is using NTLM to authenticate to this workstation.
...
Client Machine: CLIENT01
Client IP: 10.0.1.20
NTLM Security:
NTLM Version: NTLMv1
Channel Binding: Not Supported
MIC Status: Unprotected
Status: 0x0
Status Message: STATUS_SUCCESS
The fix is Network security: LAN Manager authentication level = Send NTLMv2 response only. Refuse LM & NTLM, stored as LmCompatibilityLevel = 5. Our DC had no such value at all, so the built-in default applied. We pushed 5 through the same GPO.
Set-GPRegistryValue -Name 'NTLM Audit - Domain Controllers' -Key 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa' -ValueName LmCompatibilityLevel -Type DWord -Value 5
gpupdate /target:computer /force
The same NTLMv1 smbclient call then failed with NT_STATUS_LOGON_FAILURE, the 4023 Warning carried status 0xC000006D, and a 4625 landed in the Security log. A normal NTLMv2 login from the same box kept working. Level 5 on your DCs is the change to make first, because it only breaks clients that were sending NTLMv1. Before you push it, search the logs for these:
- 4023 Warnings on the DC itself (direct NTLMv1 logons)
- 4031 and 4033 Warnings: forwarded NTLM flagged as weak (NTLMv1, no MIC or no EPA)
- NPS servers doing PEAP or EAP-MSCHAPv2 for Wi-Fi and VPN
MS-CHAPv2 still uses NTLMv1 cryptography, according to Microsoft’s KB5066470, so an NPS server that validates against your DCs is the most likely thing level 5 breaks. Microsoft’s MS-CHAPv2 troubleshooting article covers the NPS-side setting for that case; we had no NPS server in the lab. KB5066470 also describes the separate client-side change in the October 2026 update, which blocks NTLMv1-derived credentials for single sign-on on Windows itself.
Kerberos RC4 depends on the account, not the DC
The 2026 RC4 hardening (CVE-2026-20833, KB5073381) changed the default for accounts that say nothing about encryption types. It did not remove RC4 for accounts that ask for it explicitly. There is also no switch left to flip, since Microsoft’s July 2026 update made enforcement the only mode and dropped the temporary RC4DefaultDisablementPhase value. Our DC had no policy key for it:
Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters -ErrorAction SilentlyContinue
It returned nothing, so there is no phase setting for you to inspect or change. Without -ErrorAction SilentlyContinue you would get a “Cannot find path” error instead, which means the same thing.
On client01, with the krb5.conf from the lab section in place, get a TGT and ask for both service tickets. What happens when you request the RC4-only service from a stock Ubuntu client is the part most people misread.
kinit [email protected]
kvno HTTP/modern.corp.example.com
kvno HTTP/legacy.corp.example.com
The modern account works, while the legacy one fails with a message that makes you blame the KDC:
HTTP/[email protected]: kvno = 2
kvno: KDC has no support for encryption type while getting credentials for HTTP/[email protected]
So is the DC refusing RC4 here? No. A KRB5_TRACE run showed the client asking only for aes256-cts, aes128-cts, aes256-sha2, aes128-sha2, camellia128-cts, camellia256-cts, so RC4 was never on offer. Adding allow_weak_crypto = true alone did not change that list. Only when we named RC4 in a test config did the request include it:
printf '[libdefaults]\n allow_weak_crypto = true\n permitted_enctypes = aes256-cts-hmac-sha1-96 arcfour-hmac\n default_tgs_enctypes = aes256-cts-hmac-sha1-96 arcfour-hmac\n' > /tmp/rc4.conf
KRB5_CONFIG=/tmp/rc4.conf:/etc/krb5.conf kvno HTTP/legacy.corp.example.com
With that, the fully patched Server 2025 DC issued an RC4 ticket for svc-legacy. Its Security log recorded event 4769 with ticket encryption type 0x17 (RC4) for that account and 0x12 (AES256) for svc-modern, and no KDC warning from the 201 to 209 range appeared in the System log.

Read that as a warning, not a reassurance. An explicit msDS-SupportedEncryptionTypes = 4 is still honoured and still produces RC4 tickets, so an account somebody set to RC4 years ago keeps that weakness, silently. Each account setting got a different answer from the DC in the lab:
- no value set: AES256 ticket, 0x12
- value 4, client offers RC4: RC4 ticket, 0x17
- value 4, stock MIT client: no ticket
Find every user and computer object that sets the attribute, not just users:
Get-ADObject -LDAPFilter '(msDS-SupportedEncryptionTypes=*)' -Properties msDS-SupportedEncryptionTypes | Format-Table Name,ObjectClass,msDS-SupportedEncryptionTypes -AutoSize
Expect most computer objects in that list too, because Windows machines write the attribute themselves; the accounts to chase are the ones whose value includes 4 but neither 8 nor 16. Move each RC4-only account to 0x18 (AES only). KB5073381 offers 0x24 as a compatibility setting for devices that still need RC4, but it is not a fix: it keeps the ticket itself RC4-encrypted and only upgrades the session key, so the account stays as easy to Kerberoast as before. Microsoft’s RC4 detection and remediation page also warns that an account whose password predates AES has no AES keys, so reset its password before switching, and re-export any keytab the service uses. We did not test those value changes in this lab.
An RC4-only client gets no TGT
Microsoft’s What’s new in Windows Server 2025 page says the KDC no longer issues RC4 ticket-granting tickets. To see what that looks like from a client, we built a config that offers nothing but RC4 and tried to log on.
printf '[libdefaults]\n allow_weak_crypto = true\n permitted_enctypes = arcfour-hmac\n default_tgs_enctypes = arcfour-hmac\n default_tkt_enctypes = arcfour-hmac\n' > /tmp/rc4only.conf
KRB5_CONFIG=/tmp/rc4only.conf:/etc/krb5.conf kinit [email protected]
The logon stops at the first step, before you ever get a TGT:

Nothing showed on the DC at first, because the default audit policy on a Server 2025 DC records Kerberos successes only. Turn on failure auditing before you chase any Kerberos logon issue.
auditpol /set /subcategory:"Kerberos Authentication Service" /failure:enable
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /failure:enable
After that, the same kinit left event 4771 for kenneth with status 0xe, which is KDC_ERR_ETYPE_NOTSUPP. Any device that can only speak RC4 hits exactly this. It needs a firmware or client update; the same Microsoft RC4 remediation page says that otherwise it must authenticate against domain controllers running an earlier Windows Server version.
A stopped Local KDC service is normal
Server 2025 ships a second KDC service for local-account Kerberos (IAKerb and the local KDC), which Microsoft’s NTLM roadmap post listed as pre-release for the second half of 2026. Seeing it stopped in Services alarms people, yet on our DC it was stopped by design.
Get-Service -Name *kdc* | Format-Table Name,DisplayName,Status,StartType -AutoSize
The domain KDC runs automatically, and the local one sits at Manual, which is what you should expect to see on your own DC.
Name DisplayName Status StartType
---- ----------- ------ ---------
Kdc Kerberos Key Distribution Center Running Automatic
LocalKdc Kerberos Local Key Distribution Center Stopped Manual
Leave LocalKdc alone. When Kerberos logons fail on a Server 2025 DC, check in this order:
- the
Kdcservice is running - failure auditing is on
- 4768, 4769 and 4771 for the account
- the account’s
msDS-SupportedEncryptionTypes
A status of 0xe in any of those events points straight back at encryption types.
Error messages and what caused them
Every message below came out of this lab, together with the setting that produced it.
session setup failed: NT_STATUS_NTLM_BLOCKED
The DC refused to validate NTLM that a member server forwarded, because NTLM authentication in this domain is set to a Deny option. Add the server’s name to the exception list or move the client to Kerberos. The DC logs 4004.
session setup failed: NT_STATUS_NOT_SUPPORTED
The server you connected to refuses incoming NTLM itself (Incoming NTLM traffic = Deny all accounts), and the client had no Kerberos ticket to offer. Run kinit first, or connect by host name instead of IP. The server logs 4002.
System error 1937: Authentication failed because NTLM authentication has been disabled
Your Windows machine has Outgoing NTLM traffic to remote servers = Deny all. Use the target’s name so Kerberos can work, or add it to the remote server exceptions. The client logs 4001.
kinit: KDC has no support for encryption type while getting initial credentials
The client offered only RC4 for the TGT, and a Server 2025 DC won’t issue one. Enable AES on the client. With failure auditing on, the DC logs 4771 with status 0xe.
kvno: KDC has no support for encryption type while getting credentials
Same wording, different cause. The service account allows only RC4 and a modern MIT client never asks for it, so fix the account’s msDS-SupportedEncryptionTypes rather than the client.
Setting, value and event in one table
Use this as the order of work on your own DCs. Each row is one setting we applied, the value we wrote, and what the other side saw.
| Order | Policy (Restrict NTLM unless noted) | Registry value | Result seen from outside |
|---|---|---|---|
| 1 | Audit NTLM authentication in this domain = Enable all | AuditNTLMInDomain = 7 | 8004 per pass-through logon |
| 2 | Audit Incoming NTLM Traffic = all accounts | AuditReceivingNTLMTraffic = 2 | 8002 per NTLM logon to the DC |
| 3 | Outgoing NTLM traffic = Audit all | RestrictSendingNTLMTraffic = 1 | 8001 per outgoing NTLM |
| 4 | LAN Manager authentication level = NTLMv2 only, refuse LM and NTLM | LmCompatibilityLevel = 5 | NTLMv1 logon refused, NTLMv2 fine |
| 5 | NTLM authentication in this domain = Deny all | RestrictNTLMInDomain = 7 | NT_STATUS_NTLM_BLOCKED on members |
| 6 | Add server exceptions in this domain | DCAllowedNTLMServers = CLIENT01 | Listed member works again |
| 7 | Incoming NTLM traffic = Deny all accounts | RestrictReceivingNTLMTraffic = 2 | NT_STATUS_NOT_SUPPORTED on the DC |
| 8 | Outgoing NTLM traffic = Deny all | RestrictSendingNTLMTraffic = 2 | System error 1937 |
Rows 1 to 3 only log, so they are safe on any DC; row 4 is safe once the 4023, 4031 and 4033 Warnings and your NPS servers are clean. Rows 5 to 8 belong after the audit log has been quiet for a full cycle, with every exception written down. Our GPO was linked to the whole Domain Controllers OU, which in a real domain hits every DC at once, so stage the deny rows on one DC first with security filtering. Kerberos needs no switch at all: find the accounts with RC4 set explicitly, give them AES, and let a patched Server 2025 DC handle the rest.