0X80010113

Fixing RPC_E_INVALID_IPID (0x80010113) in Windows COM

Server & Cloud Intermediate 👁 8 views 📅 May 26, 2026

COM interface pointer went stale. Happens when a server object gets destroyed or disconnected before the client finishes using it. Three main causes, each with a fix.

What's happening with 0x80010113

You're staring at RPC_E_INVALID_IPID (0x80010113). The message says “The requested object or interface does not exist.” What's actually happening here is that COM's RPC layer is trying to call a method on an interface pointer — a pointer it got from the server — but by the time the call arrives, that server says “I don't know what you're talking about.” The IPID (Interface Pointer Identifier) is a unique tag COM assigns to each interface instance. When the server's object goes away, the IPID becomes invalid. The client still holds the pointer, but it's a ghost.

The real-world scenario: you're automating Excel from a C# app, or you have an Outlook add-in that's toggling between COM objects, or maybe a legacy VB6 app talking to a Windows service. The error pops up after the code works for a few calls, then suddenly breaks. It's never random — there's always a timing or lifecycle mismatch.

Below are the three most common causes, ordered by how frequently they show up in the wild. Fixes are straightforward once you know which one you're up against.

Cause 1 — The server object was destroyed before the client finished

This is the #1 cause. Something on the server side calls Release() or the object's destructor runs while the client still holds a reference. COM reference counting usually prevents this, but there's a subtle trap: if the server is a single-threaded apartment (STA) and the client's call crosses apartments, the server can finalize the object before the client's call marshals over.

Fix it by checking your apartment model and reference count discipline.

  1. Ensure the server keeps a strong reference to the object until the client explicitly signals it's done. In C++, that means not decrementing your reference count in an OnDisconnect or cleanup routine until after you've released the client's marshaled pointer.
  2. Switch the server to a multithreaded apartment (MTA) if possible. MTA doesn't serialize calls through a single thread, so the object won't get cleaned up mid-call. You do this by calling CoInitializeEx(NULL, COINIT_MULTITHREADED) in the server's init.
  3. If you can't change the apartment model, add a manual reference count increment on the server side right before you hand out the interface pointer, and decrement only after the client releases its proxy — not earlier.

In .NET, this shows up when you're iterating over interop objects (like Excel's Workbooks) and the garbage collector finalizes the COM wrapper. The fix: call Marshal.ReleaseComObject() explicitly for each object you're done with, and don't rely on GC.Collect().

Cause 2 — DCOM timeout or network disconnect for remote objects

If your COM object lives on another machine via DCOM, the IPID can go invalid when the network connection drops or the remote server reboots mid-session. DCOM uses a ping protocol — if the server doesn't hear from the client for a while (default is 6 pings, each 2 minutes apart), it assumes the client died and cleans up the object. Your client might still be working, but the server already killed the object. That's 0x80010113 on the next call.

The fix here is either reduce the ping interval or keep the client alive with periodic calls.

  1. Increase the DCOM timeout on the server machine. Open dcomcnfg (Component Services), find your application under Component Services > Computers > My Computer > DCOM Config. Right-click your COM application, go to Properties > General, and set Default Authentication Level to Connect (not None). Then under Endpoints, adjust the Session Timeout from the default 15 minutes to something longer, like 30 minutes.
  2. On the client side, send a lightweight “heartbeat” call every 5 minutes to the remote object. A simple QueryInterface for the same interface ID is enough — it doesn't do anything but keeps the server's ping timer reset.
  3. If you control the server code, implement IPingable or use the IPing mechanism in COM+. This is overkill for most cases, but if you're running a critical automation script, it's the proper fix.

Real-world scenario: you have a VBA macro in Excel that talks to a SQL Server via a COM data object on a remote box. The macro works for 10 minutes, then throws 0x80010113. The network switch between them had a 5-second blip. DCOM didn't reconnect the object — it just killed it.

Cause 3 — The interface pointer was passed across incompatible apartments without proper marshaling

This one's trickier. You have two threads in the same process, each in a different COM apartment (e.g., STA thread talking to MTA thread). You pass a raw interface pointer from one to the other without marshaling it through CoMarshalInterThreadInterfaceInStream and CoUnmarshalInterface. COM sometimes lets you get away with this if both threads are in the same STA — but if they're in different apartments, the pointer is a direct memory address that the other apartment can't use. The RPC layer tries to call it, but the server's apartment doesn't recognize the IPID because it was never registered for that apartment.

Fix it by using the proper marshaling API.

  1. Never cast or pass a raw interface pointer between threads in a COM application. Instead, serialize the pointer with CoMarshalInterThreadInterfaceInStream on the source thread, pass the stream (which is thread-safe), and call CoUnmarshalInterface on the target thread to get a new, valid pointer.
  2. If you're using .NET, the Thread class with [STAThread] on your main method can cause this if you spawn a background thread and pass a COM object to it. The fix: set the background thread's apartment to STA as well, or marshal the object using System.Runtime.InteropServices.Marshal.GetComInterfaceForObject and Marshal.GetObjectForIUnknown across thread boundaries.
  3. Check your threading model with CoGetApartmentType in C++ or Thread.GetApartmentState() in .NET. If they differ, you need marshaling.

A common trap: passing a COM object from a Windows Forms UI thread (STA) to a Task.Run delegate. The Task thread is MTA by default. Result: 0x80010113 after the second call.

Quick-reference summary

CauseTypical scenarioSimplest fix
Object destroyed too earlyClient holds pointer, server releases objectDon't Release until client is done; or use MTA
DCOM timeout / network dropRemote object becomes unreachable for >12 minSend heartbeat calls; increase DCOM timeout
Cross-apartment pointer without marshalingTransferring COM object between threadsUse CoMarshalInterThreadInterfaceInStream

If none of these fit your case, check the Windows Application Event Log for COM errors around the same time — they'll point you to the exact server object that's dying. But 9 times out of 10, it's one of the three above. Fix the lifecycle, and the error disappears.

Was this solution helpful?