A deep technical walkthrough of diagnosing and fixing the persistent Code 56 error on a Realtek 8821CE WiFi adapter — and what it taught me about the layers of the Windows networking stack that nobody writes about.
TL;DR
If you’re hitting Device Manager Code 56 (“Windows is still setting up the class configuration for this device”) on a network adapter, and the usual fixes (driver reinstall, network reset, sfc /scannow, deleting the VMware CLSID) all fail, the culprit is almost certainly that the Network Setup Service (NetSetupSvc) is disabled or stopped. This is the service that actually executes network class configuration on behalf of NetCfg. Without it, every INetCfgClassSetup::Install call fails, NetCfg latches a NETCFG_E_NEED_REBOOT flag (0x800106D9), and no reboot will ever clear it because the service still won’t start.
# The 30-second check that would have saved me three days
Get-Service NetSetupSvc, hns, NlaSvc, DeviceInstall, DcomLaunch, RpcSs, RpcEptMapper |
Format-Table Name, Status, StartTypeIf NetSetupSvc shows Disabled or Stopped with StartType: Disabled, that’s your problem. Set it back to Manual start and start it:
Set-Service NetSetupSvc -StartupType Manual
Start-Service NetSetupSvcThen disable/enable the affected adapter in Device Manager, and Code 56 will clear within seconds.
The rest of this post explains why.
Symptoms: Is This Your Problem?
Search engines bring people here with very specific phrasings, so let me list the symptom set in plain language so you can match against it:
- A WiFi or Ethernet adapter that worked fine yesterday now shows a yellow exclamation mark in Device Manager.
- The adapter properties show the error message “Windows is still setting up the class configuration for this device. (Code 56)“.
- Right-clicking the adapter and viewing properties shows mostly blank tabs (no Driver details, no Power Management options).
- Your WiFi networks list is empty, or shows only one or two phantom networks (often labelled “unknown network”) with full signal strength.
- The adapter shows up correctly identified by name in Device Manager — Windows knows what it is, it’s just stuck.
- Reinstalling the driver doesn’t help. Even uninstalling with “delete the driver software” and rebooting changes nothing.
- Network reset from Settings doesn’t help.
netsh int ip resetandnetsh winsock resetdon’t help.- Running
netcfg -q ms_tcpipfrom elevated PowerShell returns:Could not determine whether 'ms_tcpip' is installed (error code: 0x800106d9). - Running
netcfg -s nreturns no output at all. - The Event Log shows
Microsoft-Windows-Kernel-PnPEvent ID 411 withClass Configurationin the problem text.
If most or all of these match, this post is for you.
Why Most Online “Code 56 Fixes” Don’t Work
If you’ve already Googled “Code 56”, you’ve seen variations of this list:
- Run
sfc /scannow. - Run
chkdsk. - Reset the network from Settings.
- Disable IPv6.
- Uninstall the network adapter and reboot.
- Update the BIOS.
- Roll back the driver.
- Delete
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{3d09c1ca-2bcc-40b7-b9bb-3f3ec143a87b}(a leftover VMware class installer registration).
The last one — the VMware CLSID deletion — is the closest to being a real fix, and it actually does work for the specific subset of people whose Code 56 is caused by a broken VMware Workstation/Player install. With 244+ “helpful” votes on Microsoft Q&A, it’s the canonical answer for this error code on the web. But if you don’t have a broken VMware install, deleting that key does nothing, and you’re back to staring at the yellow exclamation mark wondering why no advice on the internet works for you.
The reason is that Code 56 is not one bug. It’s a symptom that gets emitted whenever a specific layer of the Windows networking stack — the class configuration layer — fails to complete its work. The reasons for that failure form a long list, and most online articles enumerate the easy ones without explaining the layer itself.
To debug it properly you need to understand how the Windows networking stack actually configures network adapters. Let me walk through that, because I had to learn it the hard way.
What Code 56 Actually Means: A Look at the Windows Networking Stack
When you plug in a network adapter (or one wakes up from suspend, or one gets a driver update), Windows runs through a chain of stages before the device is usable. Code 56 is emitted at a very specific point in that chain. Here’s the sequence, simplified:
1. PnP enumeration
The Plug and Play (PnP) manager detects the device on its bus (PCI, USB, etc.). For WiFi cards, that’s the PCIe bus advertising e.g. PCI\VEN_10EC&DEV_C821&SUBSYS_304C1A3B&REV_00. PnP creates a devnode for it — a kernel-level representation of the device — and notes which setup class it belongs to. For network adapters, that’s class {4d36e972-e325-11ce-bfc1-08002be10318}.
2. Driver matching and function-driver load
PnP searches the DriverStore (C:\Windows\System32\DriverStore\FileRepository\) for an INF that claims this hardware ID. It picks the highest-ranked match, copies the driver into place, and loads the function driver into the kernel. For a Realtek 8821CE, that’s RTWlanE.sys. SetupAPI logs each step in C:\Windows\INF\setupapi.dev.log.
At this point the driver is technically attached. But the device is not yet usable as a network adapter. There’s still post-install work to do, and it’s at this step that Code 56 happens.
3. Class configuration via NetCfg
The Net class has a registered class installer — a COM component (in netcfgx.dll) that runs after the function driver attaches and is responsible for plumbing the new adapter into the network stack. This is where things like:
- Binding standard protocols (TCP/IP, NetBIOS, Microsoft client/server) to the new adapter.
- Registering it as an interface available to the network stack.
- Setting up filter drivers and notify objects (e.g. WFP filters, virtual switch extensions).
- Generating the
NetCfgInstanceIdGUID that everything else uses to refer to this adapter. - Updating registry entries under
HKLM\SYSTEM\CurrentControlSet\Control\Network\{4d36e972...}so that other Windows components can find and use it.
The class installer is invoked through the INetCfg, INetCfgClass, and INetCfgClassSetup COM interfaces. PnP queues this work and waits for it to complete. While it’s waiting, the device’s DEVPKEY_Device_PostInstallInProgress property is set to True. If the post-install work never completes, that property stays True forever — and PnP reports the device’s problem code as CM_PROB_NEED_CLASS_CONFIG, which is what Device Manager shows you as “Windows is still setting up the class configuration for this device. (Code 56)“.
So at its core, Code 56 means: The driver attached, but the post-install class-configuration work was queued and never finished.
4. The bit nobody documents: who actually executes the work
Here’s where it gets interesting and where the available online documentation evaporates. NetCfg’s COM interfaces are the façade. The actual work — modifying the registry, generating GUIDs, wiring bindings — runs out-of-process inside a Windows service called the Network Setup Service, short name NetSetupSvc.
When you call INetCfgClassSetup::Install, the COM object marshals the call across to NetSetupSvc, which performs the registry edits and then signals back. If NetSetupSvc isn’t running, the call fails. And NetCfg’s response to a failed Install/DeInstall call is to set a flag indicating a previous transaction is incomplete and a reboot is required to complete it. That flag is NETCFG_E_NEED_REBOOT, HRESULT 0x800106D9. Once it’s set, every subsequent call into NetCfg fails immediately with the same error, until the flag clears.
The flag is supposed to clear when a Install or DeInstall call eventually succeeds. But if NetSetupSvc is permanently broken or disabled, no Install will ever succeed, and the flag will never clear. Reboots don’t help, because rebooting doesn’t auto-start a service that’s been set to Disabled.
5. The post-install runner: DeviceInstall service
There’s also a separate service involved: DeviceInstall (“Device Install Service”). This is a trigger-started service that runs the post-install phase of any PnP install — including the call into the Net class installer. It’s distinct from NetSetupSvc but works in concert: PnP triggers DeviceInstall, DeviceInstall calls into NetCfg, NetCfg delegates to NetSetupSvc.
So the real dependency chain for a WiFi adapter to come online is:
PnP → DeviceInstall → NetCfg (netcfgx.dll) → NetSetupSvc → registry/binding plumbing → Adapter alive
Anywhere that chain breaks, you get Code 56.
6. Adjacent services that can also break things
hns(Host Network Service): Provisions Hyper-V virtual switches and container networking. Goes through the same NetCfg/NetSetupSvc pipeline, so a broken HNS can flood the same pipeline with failing transactions.NlaSvc(Network List Service): Discovers networks and signals their presence — needed for network profiles and the network list UI.DcomLaunch,RpcSs,RpcEptMapper: COM and RPC infrastructure underneath everything else. NetCfg-as-COM-facade depends on these.
If any of these are stopped or disabled inappropriately, the symptom can present as Code 56 even though the immediate cause is downstream.
How to Diagnose Code 56 Properly
Now that the layers make sense, here’s the diagnostic path that would have saved me three days. Run all of these from elevated PowerShell.
Step 1: Confirm what the device’s actual problem state is
$id = '<your device InstanceId>' # e.g. 'PCI\VEN_10EC&DEV_C821&...'
Get-PnpDevice -InstanceId $id | Select Status, Problem, ProblemDescription
(Get-PnpDeviceProperty -InstanceId $id -KeyName 'DEVPKEY_Device_PostInstallInProgress').DataFor Code 56 you’ll see CM_PROB_NEED_CLASS_CONFIG and True. This confirms class-config has been queued but never finished — the driver layer is fine; the issue is everything above the driver.
Step 2: Test whether NetCfg itself is functional
netcfg -q ms_tcpip
netcfg -s nnetcfg -q ms_tcpip should print something like 'ms_tcpip' is installed.. If it returns Could not determine whether 'ms_tcpip' is installed (error code: 0x800106d9), NetCfg is in the latched NEED_REBOOT state. netcfg -s n should print every registered network component; if it returns nothing, NetCfg is blocked.
Step 3: Check the services in the pipeline
This is the step I missed for far too long:
Get-Service NetSetupSvc, hns, NlaSvc, DeviceInstall, DcomLaunch, RpcSs, RpcEptMapper |
Format-Table Name, Status, StartTypeExpected healthy state:
| Service | Status | StartType |
|---|---|---|
NetSetupSvc | Stopped or Running | Manual (trigger) |
hns | Stopped or Running | Manual |
NlaSvc | Running | Automatic |
DeviceInstall | Stopped or Running | Manual (trigger) |
DcomLaunch | Running | Automatic |
RpcSs | Running | Automatic |
RpcEptMapper | Running | Automatic |
If anything is Disabled or has an unexpected Stopped state with the wrong start type, that’s your culprit. Most commonly: NetSetupSvc set to Disabled because of a high-CPU loop someone fixed by disabling it (more on that below).
Step 4: Look at SetupAPI logs for class-installer specifics
C:\Windows\INF\setupapi.dev.log is verbose but searchable. Filter for your device’s hardware ID, and look for sections starting with >>> [Device Install ...] near the time of the failure. Lines beginning !!! indicate errors, and the most damning one for this kind of bug looks like:
!!! ump: Failed to control DeviceInstall service. Error = 0x00000425
ump: DeviceInstall service is not started.
Error 0x425 is ERROR_SERVICE_NOT_ACTIVE. If you see this, PnP is trying to invoke DeviceInstall to run the class-config phase and failing because the service isn’t running.
How to Fix Code 56 — Step by Step
The fix that worked for me
# 1. Restore NetSetupSvc to its default startup
Set-Service NetSetupSvc -StartupType Manual
Start-Service NetSetupSvc
# 2. Restore HNS too if it's also disabled
Set-Service hns -StartupType Manual
Start-Service hns
# 3. Force PnP to retry class-config on the affected adapter
$id = 'PCI\VEN_10EC&DEV_C821&SUBSYS_304C1A3B&REV_00\00E04CFFFEC8210100' # your device's InstanceId
Get-PnpDevice -InstanceId $id | Disable-PnpDevice -Confirm:$false
Start-Sleep 3
Get-PnpDevice -InstanceId $id | Enable-PnpDevice -Confirm:$false
# 4. Verify
Get-PnpDevice -InstanceId $id | Select Status, Problem
netcfg -q ms_tcpipYou should see Status: OK, Problem: 0, and NetCfg should respond normally instead of 0x800106D9. WiFi networks list will repopulate within seconds.
If NetSetupSvc isn’t disabled but Code 56 persists
Work through the layers in order:
- Check
DeviceInstallservice. Same approach: should beManual, notDisabled. - Look for zombie devices in the Net class.
Get-PnpDevice | Where-Object { $_.Status -ne 'OK' -and $_.Class -eq 'Net' }. Common offenders areROOT\VMS_VSMP\0000andROOT\VMS_MP\0000— Hyper-V virtual switch components left in a broken state by a half-finished feature uninstall. Remove them withpnputil /remove-device "ROOT\VMS_VSMP\0000"and equivalent. - Check the VMware CLSID.
reg query "HKLM\SOFTWARE\Classes\CLSID\{3d09c1ca-2bcc-40b7-b9bb-3f3ec143a87b}". If it exists and you don’t have a working VMware install, delete it (back up first withreg export). This is the canonical “VMware-broke-my-network” Code 56 fix. - Run
dism /online /cleanup-image /restorehealthfollowed bysfc /scannow. Audits and repairs the system component store andsystem32. Won’t fix registry-level NetCfg state, but will fix corruption in the DLLs NetCfg depends on. - In-place repair install. Mount a current Windows 10 22H2 (or 11) ISO, run
setup.exe, choose “Keep apps and files”. Rebuilds the entire networking stack registration without losing your apps or data. This is the nuclear option that actually works.
Why NetSetupSvc Gets Disabled in the First Place
NetSetupSvc has a long-standing reputation for occasionally entering a high-CPU loop, sometimes consuming an entire core for hours. This usually happens after a Windows feature update, a botched driver install, or a corrupted network profile. The most common “fix” people apply is to set it to Disabled to make the high CPU stop.
That works in the short term, because NetSetupSvc is trigger-started and only runs when network class configuration is needed. If you don’t install or remove any network components, you’ll never notice it’s disabled.
The trap is set when you eventually do something that triggers class configuration. In my case, it was installing Ollama and a Python ML environment, which under the hood pulled in WSL2’s Virtual Machine Platform feature. That feature install queued network class-config work for the Hyper-V virtual switch. With NetSetupSvc disabled, the work failed. NetCfg latched NEED_REBOOT. The next time my WiFi adapter went through any class-config event (a driver update, a wake-from-sleep, anything), it inherited the latched state and got stuck on Code 56.
The lesson: don’t disable NetSetupSvc to fix high CPU. Find the root cause of the loop instead. Common culprits are corrupt WMI repositories (winmgmt /verifyrepository), stuck network profiles, or a specific bad NIC driver. Disabling the service kicks the can down the road and creates a much harder problem later.
Why You Won’t Find This Online
This level of detail about the NetCfg → NetSetupSvc → DeviceInstall chain is essentially absent from public documentation. Microsoft’s developer docs cover the COM interfaces (INetCfg, INetCfgClass, etc.) for people writing network class installers, but they don’t explain the runtime service architecture. The result is that everyone debugging Code 56 from the user side ends up in the same dead end: driver reinstall, network reset, BIOS update, repeat.
The few high-quality answers that exist (the VMware CLSID fix, the Tom’s Hardware “system restore worked” thread) are correct for the specific cause they ran into. They just don’t generalise.
I’m writing this post in the hope that the next person who hits Code 56 finds it via a search like “netcfg 0x800106D9” or “PostInstallInProgress stuck true” or “NetSetupSvc disabled WiFi broken”, and gets to the fix in five minutes instead of three days.
How to Fix Code 56 on Realtek 8821CE Specifically
The Realtek 8821CE is a popular OEM card on Gigabyte, ASUS, HP, Dell and Lenovo systems, and it’s commonly cited in Code 56 reports — not because the card itself is buggy but because it’s the most-likely-to-be-affected card on systems where a Hyper-V or VPN-related install has corrupted NetCfg state. The card uses driver netrtwlane.inf with service RTWlanE and an upper filter vwifibus. None of those are unusual.
If you’re hitting Code 56 specifically on the 8821CE:
- Run the diagnostic steps above. Don’t bother sourcing alternate driver versions (Realtek’s site is painfully slow and the Gigabyte/ASUS-supplied drivers work fine).
- Don’t reseat the M.2-E module unless software paths fail completely. The card almost certainly is not faulty.
- The adapter being able to scan and show even a single network with high signal strength is positive evidence that the radio works — Code 56 is software-side.
The fixes in priority order are the same as above: NetSetupSvc → DeviceInstall → zombie devnodes → VMware CLSID → DISM/SFC → repair install.
How the Windows Networking Stack Actually Works (Layer by Layer)
If you’ve read this far you might appreciate one more pass at the full picture. Here’s the layering from kernel up to user-visible “I have WiFi”:
- Bus driver and PCI/USB enumeration. Hardware shows up on the bus.
- PnP devnode creation.
\Device\PCI...\etc. PnP queries the device’s setup class. - Function driver load. INF matched,
.sysloaded into kernel. NDIS-based for network drivers. - NDIS miniport registration. The function driver registers with NDIS.
- DeviceInstall service runs the post-install phase. Trigger-started by PnP.
- NetCfg COM facade invoked.
netcfgx.dllINetCfgClassSetup::Installetc. - NetSetupSvc executes the work. Out-of-process registry and binding modifications.
- Bindings and protocols attached. TCP/IP, IPv6, LLDP, NetBT, WFP filters bind to the new miniport.
NlaSvcnotices a new interface. Network list updates, profile selected.WlanSvc(for WiFi) takes over. Scans, applies profiles, manages association/auth.- DHCP, IP config, routing. TCP/IP stack acquires an address.
- Application-visible. Browsers, apps, etc. can use the network.
Code 56 is a failure at step 6 or 7. Everything above step 5 has succeeded; everything below step 7 is waiting. That’s why the radio can be scanning, the driver can be loaded, the device can be identified by name in Device Manager, and yet your network list is empty and properties are blank — the adapter never finished registering itself with the higher network stack.
TL;DR Cheat Sheet
For people who skipped to the end:
- Code 56 = “class configuration didn’t finish”.
- Class configuration is run by NetCfg (COM facade) which delegates to NetSetupSvc (real worker) coordinated by DeviceInstall (PnP post-install runner).
- If NetSetupSvc, DeviceInstall, or HNS is
Disabled, class configuration can’t complete, and NetCfg latches0x800106D9 NETCFG_E_NEED_REBOOTpermanently. - Reboots don’t clear the latch because the disabled service still doesn’t start.
- The fix:
Set-Service NetSetupSvc -StartupType Manual; Start-Service NetSetupSvc, then disable/enable the affected adapter. - Don’t disable NetSetupSvc to fix a high-CPU loop. Find the actual cause of the loop.
If this saved you time, share it. The next person Googling at 2am with no internet on their main machine will appreciate it.