Notice: Due to size constraints and loading performance considerations, scripts referenced in blog posts are not attached directly. To request access, please complete the following form: Script Request Form Note: A Google account is required to access the form.
Disclaimer: I do not accept responsibility for any issues arising from scripts being run without adequate understanding. It is the user's responsibility to review and assess any code before execution. More information

Windows Server SPP Token Corruption: 2GB RAM Restriction Issue


I recently encountered a perplexing issue where one of our Windows Server machines (this is not specific to a certain version) was mysteriously restricted to only 2GB of available RAM, despite being allocated more than that. The server was experiencing severe performance issues especially when the application running on the server required more than 2 GB of RAM.

After investigation, I discovered this was caused by Software Protection Platform (SPP) token corruption following an unexpected shutdown (Event ID 6008). When the SPP tokens become corrupted, Windows enters "Reduced Functionality Mode" and enforces hardware restrictions, including limiting available memory to approximately 2GB.

The Root Cause

The issue stems from corrupted or missing SPP licensing tokens. When Windows experiences an unexpected shutdown while the SPP service is writing licensing data, the token files can become corrupted or deleted entirely. This triggers Windows licensing enforcement, which restricts system resources as a protective measure.

Key indicators:

  • Event ID 6008 (unexpected shutdown) in System Event Log
  • slmgr /dlv returns "notification not activated"
  • Error code 0xC004E015 when attempting to activate
  • Available RAM restricted to ~2GB regardless of allocated memory

Detection and Diagnosis

Event Log 

I checked the Application Event Log and under the Event ID 1003, from the Source Security-SPP, I noticed this event on the degraded server:

The Software Protection service has completed licensing status check.
 Application Id=55c92734-d682-4d71-983e-d6ec3f16059f
 Licensing Status=
 1: 21c56779-b449-4d20-adfc-eece0e1ad74b, 1, 1 [(0 [0xC004E002, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 [0x00000000, 0, 0], [( 6 0xC004F009 0 0)( 1 0x00000000)( 6 0xC004F009 0 0)(?)(?)(?)( 10 0x00000000 msft:rm/algorithm/flags/1.0)( 11 0x00000000 0xC004E002)])]
 2: 22105925-48c3-4ff4-a294-f654bb27e390, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 3: 2e7a9ad1-a849-4b56-babe-17d5a29fe4b4, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 4: 3c006fa7-3b03-45a4-93da-63ddc1bdce11, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 5: 3c2da9a5-1c6e-45d1-855f-fdbef536676f, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 6: 562634bb-b8d8-43eb-8325-bf63a42c4174, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 7: 58448dfb-6ac0-4e06-b491-07f2b657b268, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 8: 661f7658-7035-4b4c-9f35-010682943ec2, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 9: 942efa8f-516f-46d8-8541-b1ee1bce08c6, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 10: 9db83b52-9904-4326-8957-ebe6feedf37c, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 11: a43f7b89-8023-413a-9f58-b8aec2c04d00, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 12: cbf3499f-848e-488b-a165-ac6d7e27439d, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 13: d6992aac-29e7-452a-bf10-bbfb8ccabe59, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 14: d839f159-1128-480b-94b6-77fa9943a16a, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 15: e73aabfa-12bc-4705-b551-2dd076bebc7d, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
 16: fea51083-1906-44ed-9072-86af9be7ab9a, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
This was the same event from a working server:
The Software Protection service has completed licensing status check.
Application Id=55c92734-d682-4d71-983e-d6ec3f16059f
Licensing Status=
1: 179bbfdb-3b18-4fa6-af8f-86f740f28fef, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
2: 22105925-48c3-4ff4-a294-f654bb27e390, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
3: 2e7a9ad1-a849-4b56-babe-17d5a29fe4b4, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
4: 3c006fa7-3b03-45a4-93da-63ddc1bdce11, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
5: 3c2da9a5-1c6e-45d1-855f-fdbef536676f, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
6: 60d99e35-ba21-46e5-abf9-877d5dd815de, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
7: 661f7658-7035-4b4c-9f35-010682943ec2, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
8: 8c1c5410-9f39-4805-8c9d-63a07706358f, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
9: 9db83b52-9904-4326-8957-ebe6feedf37c, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
10: a2ae7054-d580-4c06-a79b-1662e6f6955c, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
11: afd55ac6-d0b0-4812-9047-6c756d82bedf, 1, 1 [(0 [0x00000000, 1, 0], [(?)( 1 0x00000000)(?)( 2 0x00000000 0 0 msft:rm/algorithm/hwid/4.0 0x00000000 0)(?)(?)( 10 0x00000000 msft:rm/algorithm/flags/1.0)(?)])(1 )(2 )(3 )]
12: c0b765fd-6e2e-42f9-80d7-4a7ca0d118cf, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
13: d6992aac-29e7-452a-bf10-bbfb8ccabe59, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
14: e73aabfa-12bc-4705-b551-2dd076bebc7d, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
15: f3d100a3-7544-4580-be0b-88d452b4a881, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]
16: f70cf82b-0a95-4f14-a0a9-cb968d337962, 1, 0 [(0 [0xC004F014, 0, 0], [(?)(?)(?)(?)(?)(?)(?)(?)])(1 )(2 )(3 )]

They look similar right ? Nope they are not, this fooled me for a moment, lets explore:

❌ Failed / Problematic Log

Active entry = #1 (21c56779-...) Shows 1,1 (installed and active).

But inside it you see:

  1. 0xC004E002 → license store inconsistent
  2. 0xC004F009 → grace period expired
  3. Mixed with 0x00000000 → success

This means Windows did find a license, but it's likely corrupt and cannot read it.

Entries (#2–#16) → 1,0 with 0xC004F014 (no key). These are just unused editions, normal.

✅ Working Log

Active entry = #11 (afd55ac6-...) Shows 1,1 (installed and active).

In addition to that you also see:

  1. 0x00000000 = success only, no grace-period or inconsistent store codes.
  2. Includes hwid/4.0 → indicates it’s a clean hardware-tied activation (OEM/retail digital license).
  3. Other entries (#1–#10, #12–#16) → 1,0 with 0xC004F014 (no key). Again, normal placeholders.

Azure Log Analytics Query

I used a log analytics to query to quickly detect affected systems in Azure

Perf
| where ObjectName == "Memory"
| where CounterName == "Available MBytes"
| where CounterValue < 150
| summarize count() by Computer
| where count_ > 50
| order by count_ desc

This query identifies servers that consistently show very low available memory (under 150MB), with more than 50 data points indicating persistent restriction rather than temporary high usage - however, this will also include all servers that are using all the available memory and have exhausted their memory allocation, not specifically for this problem.

Event Log Interrogation  

If we look at the event, log entry from above we can create the following KQL which will search all the event log centrally for this rogue event.

Unfortunately, if the servers are older than Server 2016 the data may not be present in your SIEM - unless you have set up WEF (Windows Event Forwarding) to the SIEM.

WindowsEvent
| where TimeGenerated > ago(30d)
| where EventData == "Application"
| where Provider == "Security-SPP"
| where EventID == 1003
| where EventData contains "0xC004E002"  // License store inconsistent
   or EventData contains "0xC004F009"    // Grace period expired
   or EventData contains "0xC004E015"    // EUL consumption failed
| extend Computer = Computer

File System Investigation

The critical diagnostic was examining the SPP token store location:

Path: C:\Windows\System32\spp\store\2.0\

Normal system contains:

  • tokens.dat (required licensing file)
  • cache folder

Corrupted system:

  • Missing tokens.dat file
  • May contain tokens.bar (from previous repair attempts)

The absence of tokens.dat or a truncated versions the definitive indicator of SPP token corruption.

The Solution - One reboot, One reboot only!

Step 1: Stop SPP Service

net stop sppsvc

Step 2: Clean Up Old Token Files (if present)

cd %windir%\system32\spp\store\2.0
del tokens.bar

Step 3: Start SPP Service

net start sppsvc

Step 4: Recreate License Tokens

cscript.exe %windir%\system32\slmgr.vbs /rilc

The /rlic (Reload Install LiCense) command is the critical step that forces the Software Protection Platform to rebuild the licensing token store from scratch, creating a new tokens.dat file.

Step 5: Restart Server

Restart the server to ensure all licensing changes take effect - there is talk about multiple reboots - this, however, for my scenario was not required a single reboot fixed the problem.

Verification

After applying the fix:

  • slmgr /dlv should show proper activation status
  • Available RAM returns to expected levels
  • System performance is restored
  • New tokens.dat file appears in the SPP store

Conclusion

This SPP token corruption issue can be particularly challenging to diagnose because the symptoms (poor performance due to RAM restriction) don't immediately point to a licensing problem. The Azure Log Analytics query provides an effective way to identify affected systems across large environments, while the file system check offers definitive confirmation of the root cause.

The fix is straightforward once identified, but the key insight is that the /rilc command is essential for recreating the missing tokens.dat file that Windows requires for proper licensing validation.

Previous Post Next Post

نموذج الاتصال