SEC_E_INVALID_TOKEN (0x80090308) – What Actually Causes It
This error means Windows Security Support Provider Interface (SSPI) received a corrupted or malformed authentication token. Usually from SSL/TLS handshake issues, corrupted Kerberos tickets, or outdated crypto settings.
1. TLS Protocol Mismatch (Most Common)
What's actually happening here is that Windows or an app (like PowerShell remoting, .NET client, or IIS) tries to talk to a server using TLS 1.0 or 1.1, but the server has those disabled. The handshake fails, and SSPI spits out SEC_E_INVALID_TOKEN with error code 0x80090308.
You'll often see this when:
- Running
Invoke-Commandin PowerShell to a remote machine that only has TLS 1.2 enabled. - Connecting to an older Exchange or SQL Server from a Windows 10/11 machine that disabled old TLS by default.
- Using a .NET app targeting .NET Framework 4.6 or older, which doesn't default to TLS 1.2.
Fix 1: Force .NET to Use TLS 1.2
The quickest test – run this in PowerShell before your failing command:
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
If that works, you need to set this globally. Either add to your app's startup code:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls13;
Or set the registry for all .NET apps:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
Restart the app or reboot. This tells .NET to use TLS 1.2+ by default instead of negotiating down to older versions.
Why this works: The registry key SchUseStrongCrypto forces the .NET framework to use the latest Schannel protocols. Without it, .NET 4.x may try TLS 1.0 first, get rejected, and then fail with the invalid token error instead of retrying with a higher version.
2. Corrupted or Expired Kerberos Ticket
This one hits when you're in a domain environment and your Kerberos ticket is stale or corrupted. The error shows up in services like Remote Desktop (RDP), file shares, or SQL Server authentication with Windows integrated security.
You'll know it's Kerberos if the error appears after you've been logged in for a while, or after changing your domain password.
Fix 2: Purge and Renew Kerberos Tickets
Open a command prompt as Administrator and run:
klist purge
# Then renew by accessing a resource – e.g.,
dir \\server\share
# or open RDP connection
# Check your new ticket
klist
If that doesn't help, flush the whole ticket cache and ask the domain controller for fresh ones:
klist purge -li 0x3e7 # Local system account tickets
del %temp%\krbtgt* /f /q # Delete cached Kerberos ticket files
ipconfig /flushdns
Why step 2 works: The -li 0x3e7 flag targets the local system account's ticket cache, which often holds stale service tickets for services like SQL or Exchange. Deleting them forces a fresh Kerberos authentication next time you connect.
3. System Time Drift (More Than 5 Minutes)
Kerberos authentication is time-sensitive. If your system clock is off by more than 5 minutes from the domain controller, the token's timestamp becomes invalid and SSPI rejects it with SEC_E_INVALID_TOKEN.
I've seen this happen after a motherboard battery dies, or when a VM's clock drifted after being paused for a long time.
Fix 3: Sync Time Immediately
Run these commands in an admin command prompt:
w32tm /resync
w32tm /query /status
If the resync fails, force it with an external time source:
w32tm /config /manualpeerlist:"time.windows.com" /syncfromflags:manual /update
net stop w32time && net start w32time
w32tm /resync
Then verify the time is within 5 seconds of the DC:
w32tm /stripchart /computer:yourdomaincontroller /samples:3
Why this matters: Kerberos tickets include a timestamp encrypted with the client's key. The server decrypts it and checks if the timestamp is within the allowed skew (default 5 minutes). If it's off by more than that, the server can't validate the token's freshness and returns the invalid token error.
Quick-Reference Summary
| Cause | Fix | Command/Key |
|---|---|---|
| TLS mismatch | Force TLS 1.2 in .NET or app | SchUseStrongCrypto=1 in registry |
| Corrupted Kerberos ticket | Purge and renew tickets | klist purge -li 0x3e7 |
| System time drift | Resync time with DC | w32tm /resync |
Start with TLS – 8 out of 10 times that's the culprit. If not, move to Kerberos tickets. Time sync is the dark horse that gets you when you least expect it.
One more thing: If you're on Windows Server 2012 or older, you might also see this error when connecting to a server that has TLS 1.0 disabled entirely. The older .NET versions (3.5, 4.0) don't support TLS 1.2 without that registry key. Upgrade to at least .NET 4.7.2 on those boxes.
Was this solution helpful?