Remediation Guides

Unconstrained Delegation: How to Find and Remove It in Active Directory

26 September 2026 8 min read

Unconstrained delegation is an Active Directory account setting (the TRUSTED_FOR_DELEGATION flag) that lets a server receive and reuse the Kerberos ticket-granting ticket (TGT) of every user who authenticates to it. To fix it, clear the flag on every account that is not a domain controller and move real delegation needs to constrained delegation (Kerberos only).

Domain controllers carry this flag by default and need it. Anywhere else it turns an ordinary application server into a place where privileged credentials pile up in memory, which is why every Active Directory assessment tool reports it.

What the scanner is actually detecting

All of these checks read the userAccountControl attribute of accounts in the domain and look for the TRUSTED_FOR_DELEGATION bit (0x80000, decimal 524288). In Active Directory Users and Computers this is the Delegation tab option Trust this computer for delegation to any service (Kerberos only). Microsoft documents the default userAccountControl value of a domain controller as 0x82000 (532480), which already includes this bit, so the tools exclude DCs and report the rest.

Scanner Finding Notes
Nessus, plugin 150485 AD Starter Scan – Unconstrained delegation Windows family, rated High. Part of Tenable’s AD Starter Scan, which Tenable describes as a preliminary check for smaller domains (up to 5,000 users, groups or machines).
PingCastle P-UnconstrainedDelegation (Ensure that no accounts are subject to unconstrained delegation) The rationale gives a count of accounts; the detail lists each DN in the user and computer sections of the report.
Tenable Identity Exposure Dangerous Kerberos Delegation (C-UNCONST-DELEG) Rated Critical. Wider scope: it also flags risky constrained and resource-based delegation and unprotected admin accounts.
Microsoft Defender for Identity Unsecure Kerberos delegation Secure Score assessment that lists non-DC entities with unsecure delegation of any type.

Real-world risk, stated honestly

When a user authenticates with Kerberos to a service on a host trusted for unconstrained delegation, the domain controller hands the service a copy of that user’s TGT, and the host keeps it in memory so the service can request tickets to other services in the user’s name. Microsoft’s own example is an IIS application pool account with unconstrained delegation: a Domain Admin who browses to the site gives it the ability to request tickets to any service, including a domain controller, as that Domain Admin.

The practical attack is credential theft from that host. An attacker who already has administrative control of the delegated server extracts the cached TGTs and reuses them. If a privileged account connects, or a domain controller is made to authenticate to the server through forced authentication techniques (PingCastle calls this out explicitly), the result can be full domain compromise.

The limits matter too:

  • It is not remotely exploitable by itself. The attacker first needs control of the delegated host or its service account.
  • Protected accounts are not delegated. Accounts marked Account is sensitive and cannot be delegated and members of Protected Users do not have their TGTs handed over.
  • Disabling the account is not a fix. PingCastle notes that the setting persists and becomes active again if the account is re-enabled.

Until the flag is gone, treat each flagged server as sitting almost at domain controller security level.

How to confirm it

Run these from any domain-joined machine with the RSAT Active Directory PowerShell module. Primary group 516 is Domain Controllers, so the first query excludes DCs.

Import-Module ActiveDirectory

# Computers trusted for unconstrained delegation, excluding domain controllers
Get-ADComputer -Filter {TrustedForDelegation -eq $true -and PrimaryGroupID -ne 516} `
  -Properties TrustedForDelegation,PrimaryGroupID,ServicePrincipalName |
  Select-Object Name,DNSHostName,Enabled,PrimaryGroupID

# User (service) accounts trusted for unconstrained delegation
Get-ADUser -Filter {TrustedForDelegation -eq $true} `
  -Properties TrustedForDelegation,ServicePrincipalName |
  Select-Object SamAccountName,Enabled,ServicePrincipalName

One LDAP query covers users, computers and managed service accounts in a single pass, using the bitwise AND matching rule:

Get-ADObject -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=524288)(!(primaryGroupID=516)))" `
  -Properties sAMAccountName,userAccountControl,primaryGroupID |
  Select-Object Name,ObjectClass,sAMAccountName,primaryGroupID

Compare the result with Get-ADDomainController -Filter * | Select-Object Name. A real DC showing up in the list above has a non-default primary group, which is a separate problem (see false positives below).

How to fix it

1. Record the current state

Export what you are about to change so rollback is a lookup, not a guess:

Get-ADObject -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=524288)(!(primaryGroupID=516)))" `
  -Properties sAMAccountName,userAccountControl |
  Select-Object DistinguishedName,sAMAccountName,ObjectClass,userAccountControl |
  Export-Csv .unconstrained-before.csv -NoTypeInformation

For each account, find out why the flag was set: check its SPNs and ask the application owner. Typical reasons are web front ends with Windows authentication that pass the user on to SQL Server, file shares or reporting services, and old requests nobody remembers.

2. Remove the flag where delegation is not needed

Set-ADComputer -Identity APP01 -TrustedForDelegation $false -WhatIf
Set-ADComputer -Identity APP01 -TrustedForDelegation $false
Set-ADUser -Identity svc-webapp -TrustedForDelegation $false

# Works for user, computer and managed service accounts (use the DN from the export)
Set-ADAccountControl -Identity "CN=gmsa-app,CN=Managed Service Accounts,DC=contoso,DC=com" -TrustedForDelegation $false

In the GUI, open the account in Active Directory Users and Computers, go to the Delegation tab and select Do not trust this computer for delegation. Restart the server afterward (or wait for existing tickets to expire) so TGTs it already holds are cleared.

3. Replace it with constrained delegation where it is needed

On the Delegation tab select Trust this computer for delegation to specified services only, then Use Kerberos only, and add only the SPNs the application calls. The PowerShell equivalent:

Set-ADComputer -Identity APP01 -TrustedForDelegation $false
Set-ADComputer -Identity APP01 -Add @{'msDS-AllowedToDelegateTo'=@('MSSQLSvc/sql01.contoso.com:1433','MSSQLSvc/sql01.contoso.com')}

Leave TrustedToAuthForDelegation at $false. That bit is the Use any authentication protocol (protocol transition) option, which Microsoft describes as security-sensitive.

Alternatively, use resource-based constrained delegation (RBCD), configured on the back-end account rather than the front end:

Set-ADComputer -Identity SQL01 -PrincipalsAllowedToDelegateToAccount (Get-ADComputer -Identity APP01)

This parameter replaces the existing list, so include every front-end principal each time. If the back-end service runs under a user or managed service account, set it on that account with Set-ADUser or Set-ADServiceAccount.

4. Protect privileged accounts regardless

Get-ADGroupMember -Identity "Domain Admins" -Recursive |
  Where-Object objectClass -eq 'user' |
  ForEach-Object { Set-ADUser -Identity $_.distinguishedName -AccountNotDelegated $true }

The GUI equivalent is Account tab, Account options, Account is sensitive and cannot be delegated. After testing, you can also add admin users to Protected Users (Add-ADGroupMember -Identity “Protected Users” -Members adm-jdoe). Microsoft lists the trade-offs: members cannot use NTLM, need AES, and get a four-hour TGT; the domain functional level must be Windows Server 2012 R2 or later; and service and computer accounts must never be added.

5. Limit who can set the flag again

The user right Enable computer and user accounts to be trusted for delegation (SeEnableDelegationPrivilege), at Computer ConfigurationWindows SettingsSecurity SettingsLocal PoliciesUser Rights Assignment in the Default Domain Controllers Policy, controls who can set it. The effective default on domain controllers is Administrators; do not widen it.

How to verify the fix and rescan

  1. Re-run the queries above. They should return nothing, or only documented exceptions.
  2. Check a single object: Get-ADComputer APP01 -Properties TrustedForDelegation,TrustedToAuthForDelegation,msDS-AllowedToDelegateTo.
  3. Test the application’s second hop as a normal user, not an admin.
  4. With Audit Computer Account Management enabled, DCs log event 4742 showing ‘Trusted For Delegation’ – Disabled. Alert on Enabled from now on.
  5. Let replication finish (repadmin /showrepl) before rescanning, since the scanner may bind to a different DC.
  6. Re-run the Nessus AD Starter Scan and the PingCastle healthcheck. Defender for Identity notes that scores and statuses update every 24 hours.

What can break and how to roll back

Anything that forwards a user’s identity to a second server: IIS or ASP.NET sites with Windows authentication calling SQL Server or file shares, reporting servers, and some middleware. The typical symptom is the second hop arriving as anonymous, for example SQL Server logging Login failed for user ‘NT AUTHORITYANONYMOUS LOGON’. Microsoft also notes that some applications, especially non-Windows ones, only work (or are only supported by the vendor) with unconstrained delegation. For those, the documented options are a formal risk acceptance, managing the server as a domain-controller-level asset, Kerberos auditing, and outbound firewall restrictions.

Also check Credential Guard: Microsoft states it blocks Kerberos unconstrained delegation, and it is on by default for eligible Windows 11 22H2 devices and for eligible domain-joined Windows Server 2025 servers that are not DCs. An application that depends on unconstrained delegation may already be failing for those users, which is one more reason to convert it.

Rollback commands:

# Temporary only: this restores the risk
Set-ADComputer -Identity APP01 -TrustedForDelegation $true

# Undo constrained delegation or RBCD
Set-ADComputer -Identity APP01 -Clear 'msDS-AllowedToDelegateTo'
Set-ADComputer -Identity SQL01 -Clear 'msDS-AllowedToActOnBehalfOfOtherIdentity'

# Undo account protections
Set-ADUser -Identity adm-jdoe -AccountNotDelegated $false
Remove-ADGroupMember -Identity "Protected Users" -Members adm-jdoe

Common false positive reasons

  • A real DC with a non-default primary group. Filters based on primaryGroupID 516 report it as a non-DC. Do not clear the flag on a DC; fix the primary group instead (Defender for Identity reports this separately).
  • Stale computer objects. The server is gone but its object still carries the flag. The finding is technically correct; delete or clean up the object after confirming.
  • Different delegation type. Tenable Identity Exposure and Defender for Identity also alert on constrained delegation and RBCD. Read which type is named before changing anything.
  • Rescanning too early. The change has not replicated to the DC the scanner queried.

Disabled accounts are not false positives, for the reason PingCastle gives above.

FAQ

Should I remove unconstrained delegation from domain controllers?

No. Domain controllers have it by default and need it. Every scanner listed here excludes them; change only non-DC accounts.

Is constrained delegation safe?

Safer, not risk-free. It limits the service to the SPNs you list, but Defender for Identity still flags constrained entries that point at sensitive services. Prefer Use Kerberos only and keep the SPN list short.

Does “Account is sensitive and cannot be delegated” close the finding?

No. It protects the accounts you mark, which is worth doing anyway, but the flagged server still collects TGTs from everyone else and scanners still report it.

Is this a Windows patch?

No. It is a directory configuration, so no update fixes it. It sits alongside other items in a Windows Server hardening checklist and needs an owner for each flagged account.

Tracking this finding across many hosts

The flag tends to come back whenever someone grants delegation to fix a broken application, so it is worth tracking over time rather than once. If you use SITEY, you can upload the .nessus export from your AD Starter Scan so plugin 150485 is tracked with your other findings, then use per-finding retest, which SITEY supports for Nessus, to confirm closure after the change. Duplicates are merged per scanner, not across scanners, so an account reported by more than one imported scanner appears once for each.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing