0X8001000B

RPC_E_CLIENT_CANTMARSHAL_DATA (0x8001000B): Fix Client Marshaling Errors

The RPC client ran out of memory or hit a bad handler while packing parameters to send. Here's the real fix and why it works.

You're staring at 0x8001000B in Event Viewer or a stack trace, and the app just won't talk to its COM server. Annoying, but it's usually one of three things and each one has a clean fix.

The fix

Before you reinstall anything, run this. It tells you whether the failure is memory-related (transient) or structural (the client is genuinely trying to send something the marshaller can't serialize).

Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='Microsoft-Windows-DistributedCOM'} -MaxEvents 50 |
  Where-Object { $_.Message -match '0x8001000B' } |
  Select-Object TimeCreated, Message | Format-List

If you see the same failing method every time — same interface, same arguments — skip step 1 and go to step 2. If the failures are scattered across different calls and correlate with load, do step 1.

  1. Relieve memory pressure on the client. The marshaller allocates a flat buffer for every parameter before the RPC call goes out. A 500 MB SAFEARRAY parameter will try to allocate 500 MB in one contiguous chunk. On a 32-bit client that's already using 1.2 GB of its 2 GB user-mode space, that allocation fails, and you get 0x8001000B instead of a clean E_OUTOFMEMORY. Real-world trigger: a VB6 or .NET x86 app that loads a big CSV, holds it in memory, then passes it to an out-of-process COM server. Fix: rebuild the client as x64, or stream the data in chunks.
  2. Check the proxy/stub for size assumptions. If you wrote the IDL, run midl /env win32 and inspect the generated _proxy.c. Look for NdrOleAllocate calls with a hard-coded size, or a [size_is] parameter paired with a long length field. A signed length that becomes negative after a cast will make the marshaller try to allocate a ridiculous buffer. The fix is to declare length parameters as unsigned long or ULONG in the IDL and rebuild both proxy and stub.
  3. Register the correct proxy/stub. If the server was built by someone else and you're consuming it, a mismatched proxy DLL (32-bit client reaching a 64-bit server through a stale proxy) will fail marshaling on parameter types the client thinks it knows. Run regsvr32 /u then regsvr32 on the proxy DLL in the matching bitness. Check with Get-ItemProperty HKLM:\SOFTWARE\Classes\Interface\{your-iid}\ProxyStubClsid32.

Why this works

What's actually happening is that the COM client, before it ever touches the network, has to flatten every [in] parameter into a contiguous byte stream that the RPC runtime can ship. That flattening is the marshaling step, and it's done by the proxy, which calls into rpcrt4.dll and ultimately NdrClientMarshal. If any of those allocations fail, or any of the type descriptors don't match what the stub on the other side expects, the runtime bails with RPC_E_CLIENT_CANTMARSHAL_DATA. The reason step 1 fixes it is that the failing allocation in NdrOleAllocate is contiguous — fragmenting your heap with a bunch of smaller blocks won't help, you need the whole chunk to fit. The reason step 2 fixes it is that the type descriptor in the generated proxy is what the runtime trusts; if it says "allocate len bytes" and len is negative, len as a size_t becomes enormous and the allocation throws. The reason step 3 fixes it is subtle: 32-bit and 64-bit proxies have different wire formats for pointer-sized types, so a mismatch produces a descriptor that doesn't match the stub's expectations, and marshaling fails before the call even leaves the process.

Less common variations

  • Custom marshaler returning wrong size. If your type uses IMarshal or a custom [wire_marshal], and GetMarshalSizeMax returns a value smaller than what MarshalInterface actually writes, the buffer overruns and the runtime reports 0x8001000B instead of a buffer-overrun error. Audit the two methods together.
  • CoInitializeSecurity called after the first marshaled call. Marshaling happens before the security context is fully set up in some cross-apartment scenarios. Move your CoInitializeSecurity call to right after CoInitializeEx, before any interface pointers cross apartments.
  • VARIANT holding a byref array to a 64-bit server from a 32-bit client. The VT_ARRAY | VT_BYREF combination is a known marshaling trap. Convert to a plain VT_ARRAY with a copy, or use SafeArrayCopy before the call.
  • Heap corruption from an earlier bug. If you've already got a heap that's been scribbled on, the marshaller's allocation can fail for reasons that have nothing to do with RPC. Run the client under Application Verifier with the Basics and Heaps checks on. If it trips, you've got a different bug wearing this error's clothes.

Prevention

Keep marshaled parameters small. A megabyte here and there is fine; half a gigabyte across an apartment boundary is asking for this error on 32-bit. Prefer streaming interfaces (IStream, IEnumXXX) over SAFEARRAY when the payload is big or unbounded. Build the client and server with the same compiler and the same MIDL, in the same bitness, and ship the proxy/stub as a pair — never mix. Add a unit test that calls the interface with the largest payload you expect in production; if it survives on a fresh process but fails on a process that's been running for a day, you've got a fragmentation problem and you need to fix the allocation pattern, not just bump the RAM.

The short version: this error means the client can't pack the parameters. Fix the packing (memory, types, bitness), and it goes away.
Related Errors in Server & Cloud
0X000005AA Fix ERROR_NO_SYSTEM_RESOURCES (0X000005AA) on Windows Server TF401019 TF401019 in Azure Pipelines: Expired SP Secrets and Other Causes Could not read sitemap Sitemap Read Error in Google Search Console Fix Event ID 1196, 1220 Cluster Failover Not Triggered: 3 Fixes That Work

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.