If your seeing these in your SQL server error log they all tie together Error 17806, Severity 20, State 14 with text like:SSPI handshake failed with error code 0x8009030c while establishing a connection with integrated security; Reason: AcceptSecurityContext failed.
Error 18452, Severity 14, State 1 with text like:Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication. [CLIENT: 10.x.x.x]
These appear in the SQL Server error log and are from the Logon source.
Summary: what this means
A client tried to connect to SQL Server using Windows Integrated Authentication. SQL Server and Windows attempted to negotiate security (Kerberos first, then NTLM if allowed). That negotiation failed. Because the client account could not be validated, SQL Server closed the connection and logged:
- 17806 for the failed SSPI (security) handshake.
- 18452 for the resulting login failure, with the “untrusted domain” wording.
This is almost always caused by one of the following:
- The client and the SQL Server are in different domains with no trust, or the trust is broken.
- The SQL Server host is in a workgroup or can’t reach a domain controller.
- Kerberos/SPN problems or time skew block Kerberos and NTLM is disabled by policy.
- The application connects by IP address while NTLM is blocked and no SPN exists for the IP.
- The client machine’s domain trust is broken (computer account issues) or the user’s ticket cache is stale.
You’ll often see the client IP in the 18452 line, which helps you track the caller. I redact it here as 10.x.x.x.
Troubleshooting playbook (step-by-step)
Work through these in order. I include quick commands and T-SQL you can paste in.
0) Confirm the pattern in the error log
-- Count 17806 and 18452 in the current error log
EXEC xp_readerrorlog 0, 1, N'17806';
EXEC xp_readerrorlog 0, 1, N'18452';
EXEC xp_readerrorlog 0, 1, N'SSPI handshake failed';
EXEC xp_readerrorlog 0, 1, N'untrusted domain';
Note timestamps and client IPs so you can test from the same hosts.
1) Check how other logins are authenticating
SELECT c.session_id, s.host_name, s.login_name, c.auth_scheme -- Kerberos | NTLM | SQL
FROM sys.dm_exec_connections AS c
JOIN sys.dm_exec_sessions AS s ON c.session_id = s.session_id
WHERE s.is_user_process = 1
ORDER BY c.auth_scheme DESC, s.host_name;
- If most Windows connections show Kerberos, your SPNs are likely fine and the problem is specific to certain clients or domains.
- If everything shows NTLM, Kerberos is not happening. That is OK if NTLM is allowed, but if group policy blocks NTLM, you’ll get 17806/18452.
Also check the server auth mode:
SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') AS WindowsOnly; -- 1 = Windows-only, 0 = Mixed
This series of errors is about Windows logins. Auth mode won’t fix it, but it tells you whether SQL logins are even an option.
2) Basic network and domain sanity checks (from the SQL Server host)
DNS and time
nslookup YourSqlHostFQDN
w32tm /query /status
Kerberos is sensitive to time skew. Keep client, server and DC within 5 minutes.
Domain reachability
nltest /dsgetdc:YOURDOMAIN
nltest /sc_verify:YOURDOMAIN
Failures here point to domain trust or DC reachability issues.
3) Kerberos SPN and service account validation
Find which account runs the SQL Server service. Then check SPNs:
setspn -L YOURDOMAIN\SqlServiceAccount
setspn -X — search for duplicate SPNs in the forest (run with domain admin rights)
For a default instance listening on 1433 you should have:
MSSQLSvc/sqlhost.yourdomain.com:1433
MSSQLSvc/sqlhost.yourdomain.com
MSSQLSvc/sqlhost:1433
MSSQLSvc/sqlhost
For a named instance on a fixed port (say 51433):
MSSQLSvc/sqlhost.yourdomain.com:51433
MSSQLSvc/sqlhost:51433
If entries are missing, add them:
setspn -S MSSQLSvc/sqlhost.yourdomain.com:1433 YOURDOMAIN\SqlServiceAccount
setspn -S MSSQLSvc/sqlhost:1433 YOURDOMAIN\SqlServiceAccount
If your instance uses dynamic ports, either pin it to a static port or keep SPNs in sync when the port changes.
On a client that is failing, inspect Kerberos tickets:
klist
klist purge & rem clear cache, then retry the connection
4) Reproduce from known-good and known-bad clients
From the SQL Server host, use a domain account to test:
sqlcmd -E -S sqlhost.yourdomain.com -Q "SELECT SYSTEM_USER, ORIGINAL_LOGIN(), auth_scheme FROM sys.dm_exec_connections WHERE session_id=@@SPID;"
- Works locally but fails remotely: look at client machine trust, DNS, firewall to DCs, or NTLM policy on the client.
- Fails everywhere: domain reachability, SPNs, or GPO blocking NTLM on the server.
If your app connects by IP address, test with the DNS name instead. Kerberos does not use IP by default. If NTLM is blocked and the app insists on IP, register IP-based SPNs (rare) or change the connection string.
5) Check domain trust and membership scenarios
Common cases and what to do:
- SQL Server is not domain-joined (workgroup).
Windows logins from a domain cannot be validated. Use SQL logins or join the server to the domain. - Different domains with no trust.
Create a two-way trust or use SQL authentication or contained database users with passwords. - Client machine’s trust is broken.
Rejoin the domain:- Remove from domain to a workgroup, reboot.
- Join back to the domain, reboot.
6) Policies that restrict NTLM
If Kerberos fails and NTLM is disabled by policy, Windows auth fails outright.
Check local security policy or ask your AD team to review:
- Network security: Restrict NTLM settings.
- LAN Manager authentication level.
As a test (in a lab), allow NTLM to confirm the diagnosis, then fix Kerberos/SPNs so you can keep NTLM restricted.
7) Application and login configuration
- Ensure the Windows principal or AD group actually has a login:
CREATE LOGIN [YOURDOMAIN\SqlUsers] FROM WINDOWS; -- if missing
ALTER SERVER ROLE [dbcreator] ADD MEMBER [YOURDOMAIN\SqlUsers]; -- example
- If you must support non-domain users or cross-forest with no trust, use SQL logins or contained database users:
ALTER DATABASE YourDb SET CONTAINMENT = PARTIAL;
CREATE USER [app_user] WITH PASSWORD = 'Strong#Pass123';
EXEC sp_addrolemember 'db_datareader', 'app_user';
Root-cause examples with fixes
A) Clients in another, untrusted domain
Symptoms: 18452 “untrusted domain”, 17806 SSPI handshake failed for those clients only.
Fix options:
- Establish a two-way forest trust between domains.
- Or create SQL logins / contained users for the application.
- Or join the SQL Server to the client’s domain if that fits your design.
B) Kerberos not working and NTLM is blocked
Symptoms: All Windows logins fail. sys.dm_exec_connections shows no Kerberos.
Fix: Register missing SPNs to the SQL Server service account, ensure the account has rights to the SPN, purge client tickets, and reconnect using the server name (not IP). Verify Kerberos in auth_scheme.
C) Connecting by IP while NTLM is blocked
Symptoms: App uses Data Source=10.x.x.x; Kerberos cannot bind to an IP; NTLM blocked by GPO; you get 17806/18452.
Fix: Change to Data Source=sqlhost.yourdomain.com and ensure SPNs exist. If the app cannot change, temporarily allow NTLM or create IP-based SPNs (not typical).
D) Broken client trust or time skew
Symptoms: Only a few machines fail; reboots sometimes “fix” it.
Fix: Rejoin those computers to the domain, make sure time sync is correct (w32tm /resync), clear tickets with klist purge.
Optional: capture more detail while you test
SQL Audit for failed logins
CREATE SERVER AUDIT Audit_FailedLogins
TO FILE (FILEPATH = 'D:\SqlAudit\', MAXSIZE = 1 GB, MAX_ROLLOVER_FILES = 10)
WITH (ON_FAILURE = CONTINUE);
CREATE SERVER AUDIT SPECIFICATION AuditSpec_FailedLogins
FOR SERVER AUDIT Audit_FailedLogins
ADD (FAILED_LOGIN_GROUP);
ALTER SERVER AUDIT Audit_FailedLogins WITH (STATE = ON);
Read it with:
SELECT event_time, succeeded, server_principal_name, client_ip, application_name, additional_information
FROM sys.fn_get_audit_file('D:\SqlAudit\*.sqlaudit', NULL, NULL)
ORDER BY event_time DESC;
Fix checklist (copy/paste)
- Confirm the error pattern with
xp_readerrorlog. - Check existing connections’
auth_scheme. - Verify DNS resolution and time sync.
- Validate domain trust from the SQL Server (
nltestchecks). - Inspect and correct SQL Server SPNs on the service account.
- Retest using server DNS name, not IP.
- If cross-domain, confirm two-way trust, or switch to SQL/contained logins.
- Rejoin failing client machines to the domain if needed.
- Keep a short-term SQL Audit on for failed logins while you validate the fix, then turn it off.
Closing notes
- 17806 is the SSPI handshake failure.
- 18452 is the resulting Windows login failure that says “untrusted domain.”
- Both are different lines describing the same failed Windows authentication attempt.
- The solution is never inside SQL Server alone. It lives in AD trust, SPNs/Kerberos, NTLM policy, DNS, and time sync. Fix those, and these messages disappear.
Discover more from SQLYARD
Subscribe to get the latest posts sent to your email.


