Quick answer
ERROR_NOT_CONTAINER (0x000004B7) means you called a registry enumeration API like RegEnumKeyEx or RegEnumValue on a key that Windows doesn't consider a container, or you opened a key without the container flag when the API requires it. Fix the flags or stop enumerating that key.
What's actually happening here
Windows distinguishes between container keys (keys that can hold subkeys) and leaf keys (keys that hold only values). This isn't a strict physical distinction — a key that has zero subkeys can still be a container if it has the REG_OPTION_CREATE_LINK or was created as a container, but the registry stores a flag called KEY_IS_CONTAINER in the key node header. When you call RegOpenKeyEx without KEY_ENUMERATE_SUB_KEYS, or you pass REG_OPTION_NON_VOLATILE where a container is expected, Windows may mark the handle as not-a-container. Later, when you call RegEnumKeyEx, the kernel checks that flag and returns 0x4B7 because it can't enumerate a non-container.
I've seen this most often in three scenarios: a 32-bit app running under WOW64 that opens a key with KEY_WOW64_64KEY but forgets KEY_ENUMERATE_SUB_KEYS; a service enumerating HKEY_PERFORMANCE_DATA as if it were a normal hive (that's a special non-container pseudo-key); and a driver or filter that calls ZwEnumerateKey on a key object that was opened as a leaf. The error is accurate — you're asking a non-container to behave like a container.
The name is misleading. Windows isn't saying the key is empty. It's saying the key object you handed to the API doesn't have container semantics at all.
Fix it with numbered steps
- Identify which API is throwing 0x4B7. Set a breakpoint on the failing call or wrap it with
FormatMessageto confirm the code. Common culprits:RegEnumKeyEx,RegEnumValue,ZwEnumerateKey,NtEnumerateKey. - Check your
RegOpenKeyExflags. For enumeration you needKEY_ENUMERATE_SUB_KEYS(0x0008). If you opened with onlyKEY_QUERY_VALUEorKEY_READ, some paths will still succeed, but the resulting handle may not be flagged as a container. Reopen with the full rights:RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ | KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY, &hKey); - Verify the key is actually a container before enumerating. Call
RegQueryInfoKeyand inspectlpcSubKeys. If it returns 0 and the key is a leaf, enumeration will fail with 0x4B7 on some builds. Skip it or open the parent instead. - For WOW64 apps, double-check the WOW64 flag. Mixing
KEY_WOW64_32KEYwith a 64-bit container handle triggers 0x4B7 on Windows 10 1809 and later. Pick one view and stick to it. - If the key is
HKEY_PERFORMANCE_DATA, stop. That pseudo-hive is not a container. Query it withRegQueryValueExusing the index name, notRegEnumKeyEx. Same goes forHKEY_DYN_DATAon legacy systems. - In kernel mode, check the
OBJattributes. If you opened the key object withOBJ_CASE_INSENSITIVEbut without the registry key flag, the object manager may hand you a non-container. Reopen withOBJ_KERNEL_HANDLEand the correctREG_OPTION. - Rebuild and retest against a real hive. Don't test against an in-memory or test hive — some of those don't set container flags the same way the real registry does.
If that doesn't work
- Enumerate the parent instead. If you absolutely must list subkeys of a key that refuses to behave like a container, open its parent, enumerate that, and filter results. It's uglier but it sidesteps the flag check entirely.
- Use the
RegQueryInfoKey+RegEnumKeyExpattern. CallRegQueryInfoKeyfirst to getlpcSubKeysandlpcMaxSubKeyLen. IflpcSubKeysis zero, bail out before you hit 0x4B7. If it's non-zero, the key is a container and enumeration should work — if it still fails, your handle is the problem, not the key. - Switch to
NtEnumerateKeywithKeyBasicInformation. It bypasses some of the Win32 wrapper checks and reports the actualKeyNodeInformationflags. You can read the container bit directly and decide whether to proceed. - Check for third-party registry filter drivers. Antivirus and DLP products (CrowdStrike Falcon, older Symantec Endpoint builds) hook registry enumeration and can rewrite the container flag. Test with the filter disabled to confirm.
Preventing it next time
Always open registry keys with the flags that match what you plan to do. If you're going to enumerate, pass KEY_ENUMERATE_SUB_KEYS at open time. Don't rely on KEY_READ alone — it maps to a combination that historically included enumeration, but under WOW64 and on modern Windows it doesn't always set the container bit. And treat HKEY_PERFORMANCE_DATA and HKEY_DYN_DATA as their own thing; they're not normal hives and never have been. If you're writing a driver, document which REG_OPTION flags you pass when opening key objects, because that determines container status for every subsequent enumeration call. A two-line comment in your open routine saves hours of debugging later.