java-native-access/jna · error · PdhException
PdhException(result)
Error message
PdhException(result)
What it means
PdhUtil.PdhLookupPerfNameByIndex translates a performance-counter index to its localized name via the PDH API. It wraps native return codes into PdhException; at this point the first (size-query) call returned a code that is neither ERROR_SUCCESS, PDH_MORE_DATA, nor PDH_INVALID_ARGUMENT, so the failure is raised immediately with the raw code.
Solutions
- Check the numeric code carried by PdhException against the PDH error constants to identify the exact failure
- Verify the counter index is valid for the target locale (compare against the counter table for that language)
- Repair performance-counter registry data (lodctr /r) if the table is corrupt
- If a remote machine name is passed, confirm the machine is reachable and remote performance monitoring is enabled
Example fix
// before
String name = PdhUtil.PdhLookupPerfNameByIndex(null, index);
// after
try {
String name = PdhUtil.PdhLookupPerfNameByIndex(null, index);
} catch (PdhException e) {
LOG.warn("No localized perf name for index " + index + ": " + e.getErrorCode());
name = String.valueOf(index); // fallback
} Defensive patterns
Strategy: try-catch
Validate before calling
if (index <= 0) throw new IllegalArgumentException("performance counter index must be positive"); Try / catch
try { return PdhUtil.PdhLookupPerfNameByIndex(null, index); } catch (PdhException e) { LOG.warn("PDH lookup failed, code " + e.getErrorCode()); return null; } Prevention
- Confirm the index exists in the target locale's counter table
- Repair counter data (lodctr /r) on machines with corrupt performance counters
- Cache localized names; avoid lookups against machines known to lack the counter
When it happens
Trigger: Calling PdhLookupPerfNameByIndex with an index that has no mapping in the current locale's counter table, or on a system where the PDH/performance counter registry data is damaged, returning codes like PDH_INVALID_HANDLE or PDH_CSTATUS_NO_MACHINE.
Common situations: Localizing counters across Windows versions/languages where index tables differ; missing or corrupt Perfc009.dat/PerfString.ini counter data; querying a machine (szMachineName) that is unreachable or has remote registry disabled.
Related errors
- Error occured when trying get Unknown Id
- getUnknownId
- Ras32Exception(err)
- RuntimeException(hr.toString())
- StringFromGUID2
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/d008ef89e6b6f75c.
Report an issue: GitHub.
Appendix: source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/PdhUtil.java:71
* Null-terminated string that specifies the name of the computer
* where the specified performance object or counter is located.
* The computer name can be specified by the DNS name or the IP
* address. If NULL, the function uses the local computer.
* @param dwNameIndex
* Index of the performance object or counter.
* @return Returns the name of the performance object or counter.
*/
public static String PdhLookupPerfNameByIndex(String szMachineName, int dwNameIndex) {
// Call once with null buffer to get required buffer size
DWORDByReference pcchNameBufferSize = new DWORDByReference(new DWORD(0));
int result = Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, null, pcchNameBufferSize);
Memory mem = null;
// Windows XP requires a non-null buffer and nonzero buffer size and
// will return PDH_INVALID_ARGUMENT.
if (result != PdhMsg.PDH_INVALID_ARGUMENT) {
// Vista+ branch: use returned buffer size for second query
if (result != WinError.ERROR_SUCCESS && result != Pdh.PDH_MORE_DATA) {
throw new PdhException(result);
}
// Can't allocate 0 memory
if (pcchNameBufferSize.getValue().intValue() < 1) {
return "";
}
// Allocate buffer and call again
mem = new Memory(pcchNameBufferSize.getValue().intValue() * CHAR_TO_BYTES);
result = Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, mem, pcchNameBufferSize);
} else {
// XP branch: try increasing buffer sizes until successful
for (int bufferSize = 32; bufferSize <= Pdh.PDH_MAX_COUNTER_NAME; bufferSize *= 2) {
pcchNameBufferSize = new DWORDByReference(new DWORD(bufferSize));
mem = new Memory(bufferSize * CHAR_TO_BYTES);
result = Pdh.INSTANCE.PdhLookupPerfNameByIndex(szMachineName, dwNameIndex, mem, pcchNameBufferSize);
if (result != PdhMsg.PDH_INVALID_ARGUMENT && result != PdhMsg.PDH_INSUFFICIENT_BUFFER) {
break;
}
}View on GitHub (pinned to d036ad9781)