What SEC_E_NO_IMPERSONATION (0x8009030B) actually means
You're seeing 0x8009030B (that's SEC_E_NO_IMPERSONATION) in an app log, a SQL linked server error, or an IIS response. The message reads: The security context does not allow impersonation of the client.
What's actually happening here is that the server side of an SSPI handshake received a token from the client, then tried to call ImpersonateSecurityContext or ImpersonateLoggedOnUser against that token, and the kernel said no. The token itself is fine. The problem is either the server's own account lacks the privilege to impersonate, or the security context created during the handshake was marked as not impersonatable (for example, a context opened with ISC_REQ_NO_IMPERSONATION, or a Kerberos context where the server doesn't have the SeImpersonatePrivilege right).
Common real-world triggers: a SQL Server linked server running under a custom low-privilege service account after someone tightened local policy; an IIS app pool whose identity was changed from ApplicationPoolIdentity to a plain domain user without the Impersonate a client after authentication user right; a WCF or ASP.NET service that hit a duplicate SPN and fell back to NTLM in a context where the LSA won't grant impersonation. It also shows up in DCOM activation where the caller is a protected user and the server tries to act as them.
Step 1 — The 30-second check: who is the server running as?
Before touching policy, confirm the account the failing service is running as. Half of these tickets end here.
- Open
services.mscand find the service (or in IIS, check the app pool identity). - Note the logon account. If it's
LocalSystem,NetworkService, orLocalService, impersonation is almost always allowed by default and your problem is elsewhere — skip to Step 3. - If it's a named domain user or a virtual account that someone customised, continue to Step 2.
If the service was working yesterday and stopped after a change window, the change window is the culprit. Check Group Policy updates applied to the machine and any recent app pool identity swaps.
Step 2 — The 5-minute fix: grant the missing user right
The service account needs Impersonate a client after authentication and, when it also activates COM components, Act as part of the operating system is sometimes required (avoid that one unless a vendor explicitly demands it — it's a powerful right).
- Run
secpol.msc. - Go to Local Policies → User Rights Assignment.
- Open Impersonate a client after authentication.
- Add the service account (use the
DOMAIN\svc_appform, not the display name). - Run
gpupdate /forceand restart the service.
If the box is domain-joined and a GPO is overwriting the local setting, edit it at the domain level instead. Local edits get wiped on the next policy refresh, which is why so many people “fix” this and then see it come back on Monday morning.
To verify the assignment from a command line without clicking around:
secedit /export /cfg %TEMP%\secpol.cfg
findstr /i "SeImpersonatePrivilege SeTcbPrivilege" %TEMP%\secpol.cfg
SeImpersonatePrivilege is the one you want populated with the service account SID. If it only shows *S-1-5-19, *S-1-5-20, and *S-1-5-32-544, your custom account isn't in there and that's your bug.
Step 3 — The 15-minute fix: SPNs, delegation, and context flags
If the privilege is already granted and you're still getting 0x8009030B, the problem is the security context the server is trying to impersonate, not the account's rights.
Check for duplicate or missing SPNs
Duplicate SPNs force Kerberos to fail and NTLM to take over. NTLM contexts created with default flags are impersonatable, but many frameworks open them with ISC_REQ_NO_IMPERSONATION or use a context handle from a different thread. The result is exactly this error.
setspn -X
setspn -Q HTTP/web01.contoso.com
setspn -Q MSSQLSvc/sql01.contoso.com:1433
setspn -X lists duplicates across the forest. If your service name appears twice, remove the wrong one with setspn -D and re-register against the correct account. Then purge the ticket cache with klist purge on both client and server, and retry.
Kerberos delegation
When the server needs to impersonate the client and then hop to a third system (SQL linked server, file share, another web service), you need delegation. Without it, the impersonated token is anonymous on the second hop and the impersonation step fails upstream.
- For constrained delegation, open the service account in ADUC → Delegation tab → Trust this user for delegation to specified services only → add the SPN of the downstream service.
- For resource-based constrained delegation on newer forests, use
Set-ADComputer/Set-ADUserwith-PrincipalsAllowedToDelegateToAccount. - Unconstrained delegation still works but is a security liability. Don't enable it just to make an error go away.
Framework-specific culprits
In .NET, if your code calls WindowsIdentity.Impersonate() on a token obtained via LogonUser with LOGON32_LOGON_NETWORK, impersonation works on the local box but fails across the network — by design. Use LOGON32_LOGON_INTERACTIVE or LOGON32_LOGON_NEW_CREDENTIALS (with LOGON32_PROVIDER_WINNT50) instead. For network access, NEW_CREDENTIALS is the one you want.
In IIS, app pool identity ApplicationPoolIdentity already has the impersonation right via the built-in IIS_IUSRS group. If someone switched the pool to a custom domain account, you're back to Step 2.
Confirming the fix
After any change, don't just restart and hope. Force a fresh Kerberos ticket and reproduce:
klist purge
# reproduce the failing operation
klist
# look at the client principal and the server principal — if the server principal is 'NT AUTHORITY\ANONYMOUS LOGON' or blank, you're still on NTLM
If the app is the one throwing 0x8009030B, enable the SSPI diagnostics in the app's own logging. For SQL Server linked servers, the error surfaces in the SQL error log and the linked-server provider log. For .NET apps, catch the Win32Exception and log NativeErrorCode — it'll be 1311 or similar, but the underlying SSPSI code is what matters.
One last thing: don't chase this error on the client. The client is fine. The server can't impersonate the client, and that's where every fix lives.