Quick answer: The client sent a marshalled payload the server's stub couldn't deserialize. Reset the RPC cache, verify DNS and SMB connectivity, then restart the RPC services on both ends.
I know this error is infuriating because Windows usually hides the real culprit. You'll see it on a scheduled backup, a WMI query against a remote box, or a Hyper-V live migration that worked fine last Tuesday. The stub is the little shim that packs function arguments into a message the other side can unpack. When the layouts don't match — different struct version, different endianness, a truncated buffer, or a firewall mangling the packet — the receiver's stub rejects it with STATUS_BAD_STUB_DATA. That's 0xC003000C in Windows-speak. It's not a permissions error, no matter what the event log hints at. It's a data contract problem between two processes, and 90% of the time it's environmental, not code.
Fix it: the numbered steps
- Reproduce with the smallest possible client. Don't trust the app that threw the error — it may be wrapping a lower-level call. Run this from an elevated prompt on the client and aim it at the server:
wbemtest
# Connect to \\SERVER\root\cimv2
# Run: SELECT * FROM Win32_OperatingSystem
If wbemtest also fails with 0xC003000C, you've confirmed it's RPC-layer, not application-layer. If it succeeds, the app is the problem and you should check its version against the server's.
- Flush the RPC client cache. Windows caches endpoint mappings and stale entries are a classic trigger. On both the client and server, stop the services, nuke the cache, restart.
net stop rpcss /y
net stop winmgmt /y
del /f /q %windir%\system32\LogFiles\WMI\*.*
netsh winsock reset
shutdown /r /t 0
A reboot after winsock reset isn't optional. I've watched people skip it and then file a ticket saying the fix didn't work.
- Check DNS forward and reverse. RPC uses the endpoint mapper on port 135 to negotiate a dynamic port, then connects on that port. If the client resolves SERVER to an old IP — say a decommissioned NIC from a migration — the connection lands somewhere unexpected and the reply stub is garbage. Run
nslookup SERVERandping -a SERVERfrom the client and confirm both point to the same live host.
- Open the dynamic port range. RPC picks ports 49152–65535 by default on Server 2008 R2 and later. Check your firewall on both sides:
netsh int ipv4 show dynamicport tcp
netsh advfirewall firewall show rule name=all | findstr /i rpc
If a hardware firewall is doing deep packet inspection, it can strip or reorder bytes in the RPC PDU. Turn off DPI for that VLAN and retest. Yes, really.
- Match struct versions. If this is your own RPC service, the .idl and the generated stub on the server must come from the same build. Deploying a new client without regenerating the server stub is the #1 cause I see in dev environments. The marshalled layout changed, the server is still expecting the old one.
- Look at the actual traffic. Grab a capture on the client and filter for the server:
netsh trace start capture=yes tracefile=c:\rpc.etl
# reproduce, then:
netsh trace stop
You're looking for a bind that succeeds followed by a malformed fragment. If the packets look clean but the server still complains, the mismatch is in the payload, not the transport.
If the main fix doesn't work
- Disable IPv6 temporarily. RPC over IPv6 has bitten me twice on mixed networks where the client prefers IPv6 but the server's binding is IPv4-only. Uncheck IPv6 on the NIC, reboot, retest. If it clears, you found your culprit and can fix the binding properly.
- Check for a rogue SMB signing policy. On hardened domains, mismatched SMB signing requirements can corrupt the negotiation phase. Run
Get-SmbClientConfigurationandGet-SmbServerConfigurationand compare the RequireSecuritySignature values. - Test with the firewall fully off. Not just the Windows one — the network one too. I've seen Palo Alto and Fortinet appliances rewrite RPC fragments in ways that pass their own checks but break the stub. Isolate before you escalate.
- Verify the server isn't overloaded. Under memory pressure, the RPC runtime can truncate allocations and produce malformed replies. Check
Get-Counter '\Memory\Available MBytes'on the server during the failure window.
Prevention
Pin your RPC clients and servers to matching versions in your deployment pipeline. If you're running a custom RPC service, add a version field to the struct and reject mismatches at the bind stage with a clear error instead of letting the runtime throw 0xC003000C three layers deep. And keep your RPC port range documented — half the "intermittent RPC failures" I've investigated were someone's firewall team quietly tightening a range overnight.
One more thing: if this started right after a Windows cumulative update, check the KB for known RPC/DCOM regressions before you tear your hair out. Microsoft has shipped a few over the years that broke WMI and remote management in exactly this way.