0X000003FA

ERROR_KEY_DELETED (0x000003FA) on Windows Registry Keys

You're getting 0x000003FA because your code is touching a registry key that's already been marked for deletion. Here's what's actually happening and how to fix it.

You're seeing ERROR_KEY_DELETED (0x000003FA) because some piece of code — yours, a service, or an installer — is trying to open or write to a registry key that's already been marked for deletion but hasn't fully gone away yet. The most common real-world trigger: an uninstaller calls RegDeleteKey on a key, then immediately calls RegOpenKeyEx or RegSetValueEx on the same path within the same process. Windows doesn't delete the key right away.

Other places this bites: a driver's DriverUnload routine races against a registry cleanup thread, an MSI custom action deletes a hive and then tries to re-read it, or a service running as SYSTEM and a user-mode app both hammer the same key at boot.

What's actually happening here

When you delete a registry key, the kernel doesn't rip it out of the hive immediately. It flags the key with a "deleted" marker and waits. Why? Because other threads might still hold open handles to that key or its subkeys. If the kernel freed the memory right away, those handles would dangle and you'd get a blue screen instead of a polite error code.

So the key sits in a zombie state. Its name is gone from enumeration, RegEnumKeyEx won't list it, but the underlying object is still alive until the last handle closes. Any attempt to open it during that window returns STATUS_KEY_DELETED, which Win32 surfaces as ERROR_KEY_DELETED (0x000003FA).

The reason step 3 works is that the kernel only marks a parent key for deletion once all its children have been released. If a single subkey handle is still open — say a background service opened HKLM\SOFTWARE\Vendor\App\Config and never called RegCloseKey — the parent stays in limbo forever, and every RegOpenKeyEx on that path fails with 0x3FA.

The fix

  1. Stop re-opening the key in the same code path. If you just called RegDeleteKey or RegDeleteTree, don't call RegOpenKeyEx on the same path afterward. Use the handle you already have, or skip the follow-up operation. Deleting a key and then reading it back has never been a valid pattern on Windows.
  2. Close every handle. Walk your code and make sure every RegOpenKeyEx, RegCreateKeyEx, and RegOpenCurrentUser has a matching RegCloseKey. Leaked handles are the #1 cause of keys that refuse to die. Use Process Explorer's Handles view (Ctrl+H) filtered on your process name and grep for Key to see what's still open:
handle.exe -a -p YourProcess.exe | findstr /i "Key"
  1. Wait for deletion to complete before recreating. If you need to delete and recreate a key, close ALL handles first, then poll until RegOpenKeyEx returns ERROR_FILE_NOT_FOUND (2) instead of 0x3FA. Only then create the key fresh. A simple retry loop with a short sleep works:
for (int i = 0; i < 50; i++) {
    LSTATUS s = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hKey);
    if (s == ERROR_FILE_NOT_FOUND) break;         // key is gone, safe to recreate
    if (s == ERROR_SUCCESS) RegCloseKey(hKey);    // still there, try again
    Sleep(100);
}
  1. Reboot if a service is holding the handle. If the zombie key is held by a system service (svchost, Defender, a third-party agent), you can't force it closed from user mode. A reboot flushes the hive and the key disappears. Confirm by checking whether the key reappears in regedit after a restart — if it's still there, something is recreating it on every boot, not holding it.
  2. For MSI installers, sequence your custom actions. Don't run a delete action and a write action on the same key in the same install session. Put the delete in the InstallExecuteSequence before the write, or use RemoveRegistryKey table entries and let Windows Installer handle the ordering. Custom actions that call RegDeleteKey directly are the classic source of 0x3FA in installer logs.
  3. Switch to RegDeleteTree for recursive deletes. RegDeleteKey fails on keys with subkeys on older Windows and leaves partial state. RegDeleteTree (advapi32, Vista+) removes the whole subtree in one call and marks everything consistently. Pair it with KEY_WOW64_64KEY if you're a 32-bit process working on the 64-bit view.

If it still fails

Check whether the error is coming from a different process than you think. Use Process Monitor filtered on Result is KEY_DELETED and look at the Process Name column. Nine times out of ten it's not your app — it's an antivirus filter driver, a backup agent, or a management service holding the handle.

If a specific key won't die across reboots, export it with reg export first (you'll likely get 0x3FA too, which confirms the diagnosis), then delete the parent key with reg delete /f from an elevated prompt. Deleting the parent forces all child handles to be released by the kernel, and the zombie goes away. Recreate the path afterward if you still need it.

One last thing: if you're on Windows Server 2016 or 2019 and see this during container startup, it's a known interaction with the registry virtualization layer for containers. Microsoft's fix shipped in the 2019 cumulative updates from around KB4512577. Patch before you chase it any further.

Related Errors in Windows Errors
0X00040100 0X00040100 DragDrop_S_Drop: What This Code Really Means 0X000D1103 Windows Media Player 0X000D1103 Fix: Kill the Pending Validation Loop 0X80263003 Fix DWM_E_NO_REDIRECTION_SURFACE_AVAILABLE (0X80263003) 0XC01E0304 STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE (0xC01E0304) Fix

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.