Blog Post

Ask the Directory Services Team
12 MIN READ

Reading GPSVC Like a Crime Novel

Chris_Cartwright's avatar
Feb 25, 2026

A field guide to Group Policy troubleshooting—now with logs, laughs, and fewer support tickets.

Hello again — this is Adesh Prabhu from Directory Services team.

A long time ago (and we mean a long time ago), we published a deep dive explaining how to troubleshoot Group Policy by reading the Group Policy Client Service (GPSVC) debug log. That post, A Treatise on Group Policy Troubleshooting–now with GPSVC Log Analysis! | Microsoft Community Hub,  became one of the most bookmarked resources we’ve ever written, both inside and outside Microsoft.

However, the Group Policy service debug logging lacked date information, making deep‑dive troubleshooting far more difficult than it needed to be with only timestamps.

This made it difficult to correlate to networking information or even events, if days had passed and for some reason the log file last modified date was changed, making it very difficult to correlate.

That limitation is gone.

Modern versions of Windows 11 24H2 and 25 H2 since November 2025 Preview updates include both date and time on most Group policy related logs, and while that may sound trivial, it fundamentally changes how useful this log is in real environments.

Note: When the Server operating system update becomes available, we will update this article accordingly.  

In this post, we’re going to revisit the blog post, keep all the architectural detail, and walk through how Group Policy actually works on the wire, what each phase looks like in the log, and how to read gpsvc output without guessing.

Before we touch the logs: what GPSVC really is

We still see this misunderstanding, so let’s start here.

The Group Policy Client service (GPSVC) is not optional. It is the service responsible for applying Group Policy on every Windows system, client, and server.

A few important facts:

  • GPSVC runs in its own svchost instance
  • It does not run inside Winlogon
  • If GPSVC is not running, Group Policy does not apply

The service startup type is Automatic (Trigger Start). That does not mean it’s on‑demand in the casual sense — it means Windows starts it exactly when policy processing is required, lets it do its work, and then allows it to idle.

If GPSVC cannot start or crashes, nothing else in this article matters.

Group Policy always runs in two phases (always)

Every Group Policy refresh happens in two distinct phases. Miss this distinction and the gpsvc log will never fully make sense.

Phase 1: Core Group Policy processing

This is the discovery phase. During this phase, GPSVC:

  • Locates a domain controller
  • Determines the user’s or computer’s distinguished name
  • Walks the OU hierarchy for linked GPOs
  • Identifies applicable GPOs
  • Builds the ordered policy list

No settings are applied here.
No registry. No scripts. No software installs.  That doesn’t come until the next phase.

If you’re troubleshooting why a GPO never even shows up in the Group Policy Operational log or a gpresult, this is the phase you care about.

Phase 2: Client‑Side Extension (CSE) processing

Once GPSVC knows what should apply, it moves on to how it applies.

In this phase, GPSVC:

  • Checks version numbers (GPC vs GPT)
  • Evaluates security and WMI filtering
  • Invokes each Client‑Side Extension
  • Commits policy-based configuration settings to the system

If Phase 1 succeeded but the expected GPO settings were not applied,  your issue is almost certainly here.

Enabling GPSVC debug logging

GPSVC logging is still enabled through the registry and is still extremely verbose — by design.

Create the following key and value:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Diagnostics
DWORD: GPSvcDebugLevel = 0x30002

Make sure this folder exists:
%windir%\Debug\Usermode

If that directory does not exist, gpsvc.log will not be created.

Trigger Group Policy processing using:

gpupdate /force /target:computer
gpupdate /force /target:user

Processing user and computer policies separately reduces log interleaving and makes analysis easier.

First rule of reading gpsvc.log: follow the thread

GPSVC is multi‑threaded. This means multiple operations happen at the same time, and if you don’t follow the correct thread, the log quickly turns into noise.

A modern log entry looks like this:

GPSVC(4b4.5dc) 2026-1-30 07:43:27:860 ProcessGPO(Machine):

Here’s how to read it:

  • 4b4 → Process ID (PID)
  • 5dc → Thread ID (TID)
  • Date & Time → finally present
  • Machine/User → processing context

You will typically see two primary threads:

  • One for Machine policy
  • One for User policy

Pick the context you care about and ignore the rest. Mixing threads is the fastest way to get lost.

Machine policy processing: what it looks like in the log

Machine policy always runs first.

Early in the log, you’ll see confirmation of machine context:

User SID = MACHINE SID
bMachine = 1

From here, GPSVC:

  1. Starts the service engine
  2. Waits for critical dependencies
  3. Verifies network connectivity
  4. Discovers applicable GPOs
  5. Evaluates filters and versions
  6. Saves data to local cache
  7. Calls CSEs

Note that Phase 1 is 1-4, and Phase 2 is 5-7. 

Dependency and startup signatures

GroupPolicyClientServiceMain
CGPService::Start
InitializeRPCServer starting RPCServer
Detected that this is machine Startup

This is GPSVC making sure prerequisites (RPC, COM, core subsystems) are ready before proceeding.

Connectivity waits (these matter more than people think)

A large number of “slow boot” complaints are explained right here.

Waiting for connectivity before applying policies
Waiting for SamSs with timeout 120000
Waiting for MUP with timeout 113672
Waiting for DS with timeout 109625
We have network connectivity... proceeding to apply policy.

This is expected behavior.

GPSVC will not apply policy until it believes the system is in a usable network state. The addition of more detailed timestamps makes it easy to see exactly how long these waits lasted and correlate them with NLA, Netlogon, or network traces.

OU walk and policy discovery (LSDOU)

GPSVC evaluates policies in LSDOU order.

SearchDSObject: Searching <OU=Workstations,OU=Bangalore,DC=contoso,DC=com>
Found GPO(s): <[LDAP://cn={9266...},cn=policies,cn=system,DC=contoso,DC=com;0]>
...
SearchDSObject: Searching <DC=contoso,DC=com>
Found GPO(s): <[LDAP://CN={31B2...},CN=Policies,CN=System,DC=contoso,DC=com;0]>
...
SearchDSObject: Searching <CN=Default-First-Site-Name,...>

The GUID identifies the GPO.
The trailing number after the semicolon indicates state:

  • 0 = Enabled
  • 1 = Disabled
  • 2 = Enforced

Versioning, filtering, and replication health

Once a GPO is identified, GPSVC validates it:

Machine has access to this GPO.
GPO passes the filter check.
Found functionality version of: 2
Found file system path of: \\contoso.com\sysvol\contoso.com\Policies\{31B2...}
Found display name of: <Default Domain Policy>
Found machine version of: GPC is 3, GPT is 3

If GPC and GPT do not match, you have a replication problem, either in SYSVOL or in AD.
It’s that simple.

Machine account needs read access on all user policies too in addition to user (Read & Apply)

Group Policy caching (what it actually looks like)

Caching improves synchronous processing by reusing locally stored policy data.

When caching is involved, look for these signatures:

CanStartFromLocalDataStore:++
CanLoadGPOsFromLocalCache:++
SaveGPOsToLocalCache: Saving values to local cache.
SaveGPOsToLocalCache(Machine): Successfully flip active bit of current data store.

Reading this in English:

  • Cache eligibility evaluated
  • Local policy data written
  • Active cache store committed

If you expect caching and don’t see these lines, it isn’t participating — usually because an administrator has disabled caching via the “Configure Group Policy Caching” setting.

Slow link detection (log‑driven, not event‑driven)

Slow link evaluation happens only during synchronous policy processing.

GetBandwidthThreshold: Bandwidth Threshold (WINLOGON) = 500.
GetBandwidthEstimate returned Bandwidth = 4294967.
IsSlowLink: Current Bandwidth >= Bandwidth Threshold.

GPSVC compares measured bandwidth against policy thresholds. If evaluation fails, it uses the last known state recorded in policy history.

CSE processing: the business end of Group Policy

Once discovery and validation are complete, GPSVC calls Client‑Side Extensions.

Registry CSE example

ProcessGPOs(Machine): Processing extension Registry
SetRegistryValue: Wallpaper => C:\Temp\Wallpaper\Wallpaper.jpg [OK]
LogRegistryRsopData: Successfully logged registry Rsop data

Each CSE:

  • Acquires locks
  • Applies changes
  • Reports success or failure
  • Updates RSOP data

Understanding which CSE applied which setting is often the key to resolving conflicts.

Registry CSE logging for administrative template settings is always logged in GPSVC.log, all other CSEs have its own debug logging as described in A Treatise on Group Policy Troubleshooting–now with GPSVC Log Analysis! | Microsoft Community Hub.

User policy processing

After machine policy completes, GPSVC starts the user thread:

ProcessGPO(User):

From here, the same phases repeat:

  • OU walk
  • Filter evaluation
  • Version checks
  • CSE execution

Foreground processing mode may temporarily switch to synchronous during first logon:

gpSetFgPolicyRefreshInfo (... info.mode: Synchronous)
gpSetFgPolicyRefreshInfo (... info.mode: Asynchronous)

This is expected.

When gpsvc.log isn’t enough: use TSS

For complex issues involving authentication, replication, or drivers, collect unified traces using TSS (Troubleshooting Script). TSS directory has GUI version called TSGUI.ps1 which you can use to explore different options/switches to get additional tracing capabilities.  Not all of the files will be readable, but you may find clues in the text and log files to self resolve certain issues that you may run into.  If the issue cannot be resolved, Microsoft Support can read some of the other files.  Note: always test this before executing them in production.in production.

md C:\TSS
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned -Force
Start-BitsTransfer https://aka.ms/getTSS -Destination C:\TSS\TSS.zip
Expand-Archive C:\TSS\TSS.zip -DestinationPath C:\TSS -Force
C:\TSS\TSS.ps1 -Scenario ADS_GPOEx

Full date and time are available now in all group policy debug log files, here are sample log entries that look like with date and time:

To troubleshoot group policy core engine issues:

Gpsvc.log:

GPSVC(188c.25d8) 2026-01-30 11:13:17:216 ProcessGPOs(Machine): Send a network activate for AOAC. GPSVC(188c.25d8) 2026-01-30 11:13:17:216 Passive Network activated.
GPSVC(188c.25d8) 2026-01-30 11:13:17:218 ProcessGPOs(Machine): Verbose output to eventlog requested.
GPSVC(188c.25d8) 2026-01-30 11:13:17:230 Opened Existing Registry key
GPSVC(188c.25d8) 2026-01-30 11:13:17:230 UncPath :'\\contoso.com\SYSVOL'
GPSVC(188c.25d8) 2026-01-30 11:13:17:230 UncPath :'\\contoso.com\NETLOGON'
GPSVC(188c.25d8) 2026-01-30 11:13:17:254 GetDomainControllerConnectionInfo: Enabling bandwidth estimate.
GPSVC(188c.25d8) 2026-01-30 11:13:17:278 Started bandwidth estimation successfully
GPSVC(188c.25d8) 2026-01-30 11:13:17:278 GetDomainControllerConnectionInfo: Getting Ldap Handles. GPSVC(188c.25d8) 2026-01-30 11:13:17:278 GetLdapHandle: Getting ldap handle for host: DC1.contoso.com in domain: contoso.com.
GPSVC(188c.25d8) 2026-01-30 11:13:17:289 GetLdapHandle: Server connection established. GPSVC(188c.25d8) 2026-01-30 11:13:17:300 GetLdapHandle: Binding using only kerberos. GPSVC(188c.25d8) 2026-01-30 11:13:17:324 GetLdapHandle: Bound successfully.
To troubleshoot GPMC snap-in related errors:

Gpmc.log

GPMC(5ac.8f0) 2026-01-30 11:13:47:878 Created semaphore with handle 0000000000000A84
GPMC(5ac.8f0) 2026-01-30 11:13:47:878 In Object 0x00000000029AA6C0, initializing semaphore handle to 0000000000000A84 for report 0x00000000029AEB08
GPMC(5ac.8f0) 2026-01-30 11:13:47:884 Wait on semaphore 0000000000000A84 called
GPMC(5ac.8f0) 2026-01-30 11:13:47:884 Wait on semaphore 0000000000000A84 called
GPMC(5ac.e30) 2026-01-30 11:13:49:801 CReportImpl::SetReportAsync Calling set report with 0x00000000029a2610 and 0x000000000671EE20
GPMC(5ac.e30) 2026-01-30 11:13:49:803 CCookieCutter::SetReport SetReport called with cookie 0x29a2610 and nodedeletedflag 000000000671EE20
GPMC(5ac.e30) 2026-01-30 11:13:49:803 In object 0x00000000029AA6C0, Releasing semaphore 0000000000000A84
GPMC(5ac.8f0) 2026-01-30 11:13:57:222 Clearing out 0 SIDs GPMC(5ac.8f0) 2026-01-30 11:13:58:126 In Object 0x00000000029A9EC0, initializing semaphore handle to 0000000000000A84 for report 0x00000000029AEB08 GPMC(5ac.8f0) 2026-01-30 11:13:58:126 Wait on semaphore 0000000000000A84 called
GPMC(5ac.8f0) 2026-01-30 11:13:58:126 Wait on semaphore 0000000000000A84 called
GPMC(5ac.5f0) 2026-01-30 11:13:58:418 CReportImpl::SetReportAsync Calling set report with 0x00000000029a2610 and 0x0000000003EA9920
GPMC(5ac.5f0) 2026-01-30 11:13:58:418 CCookieCutter::SetReport SetReport called with cookie 0x29a2610 and nodedeletedflag 0000000003EA9920
GPMC(5ac.5f0) 2026-01-30 11:13:58:418 In object 0x00000000029A9EC0, Releasing semaphore 0000000000000A84
 

GPmgmt log:

[5ac.8f0] 2026-01-30 15:56:36:269 [VERBOSE] GETADSIHandle: successfully bound to ds object escaped <LDAP://DC1.contoso.com/DC=contoso,DC=com>
[5ac.8f0] 2026-01-30 15:56:36:269 [VERBOSE] CForest::GetTrustedDomains was called for contoso.com forest and contoso.com domain
[5ac.8f0] 2026-01-30 15:56:36:269 [VERBOSE] CForest::GetForestAndDomain was called for CONTOSO.COM [5ac.8f0] 2026-01-30 15:56:36:273 [VERBOSE] CForest::GetForestAndDomain::DsGetDcName Forest: contoso.com Domain: contoso.com
[5ac.8f0] 2026-01-30 15:56:36:275 [VERBOSE] CForest::GetForestAndDomain was called for contoso.com [5ac.8f0] 2026-01-30 15:56:36:277 [VERBOSE] CForest::GetForestAndDomain::DsGetDcName Forest: contoso.com Domain: contoso.com
[5ac.8f0] 2026-01-30 15:56:36:277 [VERBOSE] CForest::CheckForestAndDomainTrust same forest: contoso.com [5ac.8f0] 2026-01-30 15:56:36:279 [VERBOSE] GetDomainDN: Domain FQDN of domain contoso.com = DC=contoso,DC=com

gpmgmtManaged.log:

Reporting(3620.1) 2026-01-30 15:11:26:961 Rsop::Initialize:----------------------------------------------
Reporting(3620.1) 2026-01-30 15:11:26:961 Rsop::Initialize:Namespace= root\rsop\ns7406d980_1c36_4aad_b4c9_a0942f9894dc
Reporting(3620.1) 2026-01-30 15:11:26:963 Rsop::Initialize:----------------------------------------------
Reporting(3620.1) 2026-01-30 15:11:26:963 Rsop::Initialize:Initialising computer RSOP data
Reporting(3620.1) 2026-01-30 15:11:27:073 RsopTargetResults::.ctor:Name = CONTOSO\Client1$
Reporting(3620.1) 2026-01-30 15:11:27:073 Rsop::Initialize:Initialising user RSOP data
Reporting(3620.1) 2026-01-30 15:11:27:079 RsopTargetResults::.ctor:Name = CONTOSO\policy
Reporting(3620.1) 2026-01-30 15:11:27:081 CrimsonEvtLogConsumer::.ctor:MachineName is either null or empty Reporting(3620.1) 2026-01-30 15:11:27:083 Rsop::Initialize:Namespace is of LoggedData type
To troubleshoot Group policy editor related issues:

Gpedit.log

GPEDIT(5ac.8f0) 2026-01-30 15:57:08:243 CGroupPolicyObject::New: Entering with: GPEDIT(5ac.8f0) 2026-01-30 15:57:08:245 CGroupPolicyObject::New: Domain Name: LDAP://DC1.contoso.com/DC=contoso,DC=com GPEDIT(5ac.8f0) 2026-01-30 15:57:08:247 CGroupPolicyObject::New: Flags: 0x0 GPEDIT(5ac.8f0) 2026-01-30 15:57:08:247 CGroupPolicyObject::New: Checking if DC (DC1.contoso.com) is read-only. GPEDIT(5ac.8f0) 2026-01-30 15:57:08:294 CGroupPolicyObject::New: DC (DC1.contoso.com) is NOT read-only.
To troubleshoot ADMX or ADML parsing issues:

AdmTmpl.log:

Group Policy Editor ADMX/ADML

The Group Policy Editor for Administrative Templates Registry Policy has logging on its work. It allows for example to understand in detail why it fails parsing the set of ADMX/ADML files. One example would be if files have mismatched versions that lead to:

Extension ADMX refer to OS release tags that Windows.Admx does not have.

ADMX files define policies twice as ADMX files got renamed and customer incorrectly merged sets of files.

Registry Configuration

Value Path: HKLM\SOFTWARE\Microsoft\Group Policy
Value Name: AdmTmplDebugLevel
Value Type: REG_DWORD
Value Data: 10002 (hex)

Output: %temp%\AdmTmpl.log

AdmTmpl(5f0.518) 2026-01-30 12:44:23:684 CPolicyComponentData::CreateComponent: Entering.
AdmTmpl(5f0.518) 2026-01-30 12:44:23:688 CPolicySnapIn::Initialize: Entering ... AdmTmpl(5f0.518) 2026-01-30 12:44:23:694 CPolicySnapIn::Initialize: Creating editor manager.
AdmTmpl(5f0.518) 2026-01-30 12:44:23:874 CPolicySnapIn::Initialize: Exiting AdmTmpl(5f0.2054) 2026-01-30 12:44:23:894 CPolicyComponentData::LoadTemplates: Entering for Machine AdmTmpl(5f0.2054) 2026-01-30 12:44:23:896 File does not exist: '\\contoso.com\sysvol\contoso.com\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\comment.cmtx'.
AdmTmpl(5f0.2054) 2026-01-30 12:44:23:942 PDX parser: Parsing file 'C:\Windows\PolicyDefinitions\AccountNotifications.admx'.
AdmTmpl(5f0.2054) 2026-01-30 12:44:23:985 PDX parser: Obtained appropriate PDX resource file 'C:\Windows\PolicyDefinitions\en-US\AccountNotifications.adml' for language 'en-US'. AdmTmpl(5f0.2054) 2026-01-30 12:44:23:987 PDX parser: Parsing resource file 'C:\Windows\PolicyDefinitions\en-US\AccountNotifications.adml'. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:006 PDX parser: Parsing resource file completed successfully.
AdmTmpl(5f0.2054) 2026-01-30 12:44:24:008 PDX parser: Successfully parsed file.
AdmTmpl(5f0.2054) 2026-01-30 12:44:24:008 PDX parser: Parsing file 'C:\Windows\PolicyDefinitions\ActiveXInstallService.admx'. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:010 PDX parser: Obtained appropriate PDX resource file 'C:\Windows\PolicyDefinitions\en-US\ActiveXInstallService.adml' for language 'en-US'.
AdmTmpl(5f0.2054) 2026-01-30 12:44:24:010 PDX parser: Parsing resource file 'C:\Windows\PolicyDefinitions\en-US\ActiveXInstallService.adml'. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:012 PDX parser: Parsing resource file completed successfully.
AdmTmpl(5f0.2054) 2026-01-30 12:44:24:014 PDX parser: Successfully parsed file.
AdmTmpl(5f0.2054) 2026-01-30 12:44:24:014 PDX parser: Parsing file 'C:\Windows\PolicyDefinitions\AddRemovePrograms.admx'. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:016 PDX parser: Obtained appropriate PDX resource file 'C:\Windows\PolicyDefinitions\en-US\AddRemovePrograms.adml' for language 'en-US'. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:016 PDX parser: Parsing resource file 'C:\Windows\PolicyDefinitions\en-US\AddRemovePrograms.adml'. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:024 PDX parser: Parsing resource file completed successfully. AdmTmpl(5f0.2054) 2026-01-30 12:44:24:024 PDX parser: Successfully parsed file.

Final thoughts

Group Policy hasn’t gotten simpler — but the tools to understand it have improved.

With full timestamps now present in gpsvc.log, you can finally correlate Group Policy behavior with the rest of the system instead of guessing.

If you:

  • Follow one thread
  • Respect the two‑phase model
  • Read discovery before execution

The gpsvc log will tell you exactly what happened — and why.

And yes, this is still one of the best troubleshooting tools in Windows.

Additional resources:

Troubleshooting Group Policy Using Event Logs | Microsoft Learn

Introduction to TroubleShootingScript toolset (TSS) - Windows Client | Microsoft Learn

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Updated Feb 25, 2026
Version 1.0
No CommentsBe the first to comment