NSClient - ERROR: Failed to get PDH value.
— ny_wk

The NSClient "Failed to get PDH value" error in Nagios means the Windows Performance Data Helper (PDH) subsystem cannot read CPU, memory, or disk counters because the performance counter registry is corrupt or those counters have been disabled. The fix is to rebuild the counters with lodctr /r from an elevated prompt and, if needed, re-enable the disabled counter providers in the registry.
If you monitor Windows hosts with Nagios and NSClient++ (NSClient), you have probably seen one or both of these messages in your service checks: ERROR: Could not get data for 5 perhaps we don't collect data this far back? and ERROR: Failed to get PDH value. Both point to the same root cause and both are completely fixable without reinstalling the agent or the operating system.
What "Failed to Get PDH Value" Actually Means
NSClient++ does not invent its own metrics. When a check like check_cpu, check_memory, or CheckCPU runs, the agent asks Windows for the value of a performance counter through the PDH API (the same plumbing that powers Performance Monitor, perfmon). When that API returns nothing, NSClient surfaces it as "Failed to get PDH value."
There are three usual reasons the PDH layer goes silent:
- The performance counter registry is corrupt. The index that maps counter names to numeric IDs (PERFLIB) has drifted out of sync.
- A counter provider is disabled. Providers such as
PerfOS(CPU/memory/system) carry a registry flag that can switch them off, which blocks any tool from reading those objects. - The counters were collected in a localized (non-English) build and the index/text files got out of step, which is the classic trigger for the "don't collect data this far back" wording.
A quick way to confirm the problem is host-side and not a Nagios configuration issue: open perfmon directly on the Windows server. If Performance Monitor itself throws an error when you try to add a counter, the agent was right and the rebuild below is exactly what you need.
Case 1: Rebuild the Performance Counters with lodctr
Most "Failed to get PDH value" incidents are solved purely by rebuilding the counter registry. The built-in lodctr utility re-reads every installed counter definition and regenerates a clean, consistent index.
- Open an elevated Command Prompt. Click Start, type
cmd, right-click Command Prompt and choose Run as administrator. Counter rebuilds write to protected registry hives, so a non-elevated shell will silently fail. - Move into System32. Run
cd /d C:\Windows\System32. (The single commandcd /dchanges both drive and directory in one step.) - Rebuild the counters. Run
lodctr /r. This recreates your counter values from the installed providers and may take a few moments — let it finish without interrupting it. - Resync WMI to the new counters. Run
winmgmt /resyncperf. This step is frequently skipped and is the reason a rebuild "doesn't take" — it forces the WMI performance library to register the freshly built counters. - Verify the rebuild. Run
lodctr /qto query the current state of every provider.
A healthy lodctr /q output starts with the PERFLIB base block and then lists each provider as (Enabled):
Performance Counter ID Queries [PERFLIB]
Base Index: 0x00000737 (1847)
Last Counter Text ID: 0x000031D2 (12754)
Last Help Text ID: 0x000031D3 (12755)
[.NET CLR Data]
Performance Counters (Enabled)
DLL Name: %systemroot%\system32\netfxperf.dll
Open Procedure: OpenPerformanceData
Collect Procedure: CollectPerformanceData
Close Procedure: ClosePerformanceData
Now reopen Performance Monitor and add a CPU counter. If it appears cleanly, the host is fixed — restart the NSClient++ service and the Nagios check should flip back to OK on its next interval.
Case 2: Re-enable a Disabled Counter Provider
Sometimes the rebuild succeeds but lodctr /q still shows a critical provider as (Disabled). The most common culprit is PerfOS, which feeds CPU, memory, and overall system metrics:
[PerfOS]
Performance Counters (Disabled)
DLL Name: %SystemRoot%\System32\perfos.dll
Open Procedure: OpenOSObject
Collect Procedure: CollectOSObjectData
Close Procedure: CloseOSObject
When a provider is disabled, no monitoring tool — NSClient++, perfmon, or a custom CPU monitor — can read those objects. The disable state is controlled by a single registry value per provider, and you re-enable it by setting that value to 0 (zero means "do not disable").
Make these registry changes on the affected host:
| Registry key | Value name | Set to |
HKLM\SYSTEM\CurrentControlSet\Services\PerfOS\Performance | Disable Performance Counters | 0 |
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib | Disable Performance Counters | 0 |
You can apply the same change from an elevated prompt without opening the Registry Editor:
- Run
reg add "HKLM\SYSTEM\CurrentControlSet\Services\PerfOS\Performance" /v "Disable Performance Counters" /t REG_DWORD /d 0 /f - Run
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib" /v "Disable Performance Counters" /t REG_DWORD /d 0 /f - Re-run the rebuild so the provider is re-indexed:
lodctr /rfollowed bywinmgmt /resyncperf. - Confirm the provider now reads (Enabled) with
lodctr /q.
If you have several providers disabled (for example PerfDisk or PerfProc as well as PerfOS), check each one's ...\Services\<Provider>\Performance key for the same Disable Performance Counters value and zero it.
Restoring Counters from a Clean Backup
If lodctr /r does not fully heal the index — which happens when the PERFLIB text files themselves are damaged — rebuild from Windows' own backup of the counter settings:
- From an elevated prompt, run
lodctr /R. Note the capital R: the uppercase form rebuilds the counters from scratch using the system backup store, which is more thorough than the lowercase/rresync. - Rebuild the base performance library files if needed:
cd /d C:\Windows\System32thenlodctr /r. - Resync WMI again:
winmgmt /resyncperf. - For deep corruption, you can also reload the system-supplied counter definitions per provider with
lodctragainst the matching.ini(for examplelodctr perfos.iniwhile in System32), then resync.
Common Pitfalls That Keep the PDH Error Coming Back
- Skipping the WMI resync. Running
lodctr /ralone often is not enough. Always follow it withwinmgmt /resyncperfor the agent may keep reading stale data. - Wrong architecture context. On 64-bit Windows,
C:\Windows\System32is the 64-bit path andSysWOW64is the 32-bit one. Run the rebuild from the native 64-bit prompt so all providers are indexed. - Not restarting NSClient++. The agent caches counter handles. After any rebuild, restart the service:
net stop nscp && net start nscp(older NSClient++ builds use the service namenscp; some packages register it asNSClientpp— confirm withsc query). - Disabled providers re-disabling themselves. Some third-party agents or group policies set
Disable Performance Counters=1. If the value keeps reverting, audit your GPOs and any "performance counter" maintenance scripts. - Localization mismatch. The "don't collect data this far back" wording often appears on non-English Windows. Rebuilding with
lodctr /rregenerates the localized text IDs and clears it. - Treating it as a Nagios problem. The error originates on the Windows host. Editing the Nagios command or service definition will not fix a corrupt counter index.
Verification: Confirm the Fix End-to-End
Do not declare victory until you have checked the whole path from Windows counters to the Nagios console:
- Counters enabled.
lodctr /qshows your key providers (especiallyPerfOS) as (Enabled). - Perfmon reads live data. Open
perfmon, add Processor > % Processor Time, and confirm a live graph appears with no error dialog. - PowerShell reads the counter. Run
Get-Counter '\Processor(_Total)\% Processor Time'— a numeric sample proves PDH is healthy. - Local NSClient test. From the NSClient++ install folder, run a self-test such as
nscp test(or your build's equivalent) and execute thecheck_cpuquery to see a value instead of the PDH error. - Nagios goes green. Force a recheck of the host's CPU/memory service in the Nagios web UI and confirm it returns OK with real percentages.
Once all five pass, the NSClient "Failed to get PDH value" error is genuinely resolved rather than just temporarily quiet.
Key Takeaways
- The NSClient PDH error is a Windows-host problem: the performance counter registry is corrupt or a provider is disabled, not a Nagios misconfiguration.
- Case 1 — rebuild counters from an elevated prompt with
lodctr /r, then runwinmgmt /resyncperf, then verify withlodctr /q. - Case 2 — if a provider like
PerfOSshows (Disabled), setDisable Performance Countersto0under both the provider'sPerformancekey andPerflib. - Always restart the NSClient++ service after a rebuild so it drops cached counter handles and reads fresh data.
- Verify end-to-end — perfmon,
Get-Counter, a local NSClient test, and a Nagios recheck — before closing the ticket.
Frequently Asked Questions
What does "Failed to get PDH value" mean in NSClient?
It means NSClient++ asked Windows for a performance counter through the PDH API and got nothing back. The usual cause is a corrupt performance counter registry index or a disabled counter provider on the monitored Windows host.
How do I rebuild Windows performance counters?
Open an elevated Command Prompt, run cd /d C:\Windows\System32, then lodctr /r to rebuild, and winmgmt /resyncperf to sync WMI. Use lodctr /q to confirm every provider shows as Enabled.
What is the difference between lodctr /r and lodctr /R?
Lowercase lodctr /r rebuilds the counter index from the currently installed providers. Uppercase lodctr /R performs a more thorough rebuild from the system's backup counter store, which helps when the lowercase resync alone does not clear the error.
Why is the error back after I fixed it?
Most often you skipped winmgmt /resyncperf, did not restart the NSClient++ service, or a Group Policy/agent is re-setting Disable Performance Counters to 1. Audit those, then rebuild again.
For more practical Windows monitoring and sysadmin walkthroughs, subscribe on YouTube @explorenystream.