RPC_E_CHANGED_MODE (0X80010106) Quick Fix: Thread Mode Error
RPC_E_CHANGED_MODE happens when you mix COM threading models. Here's how to fix it in 30 seconds or less, with backup plans if that fails.
What’s This Error Really Mean?
Seen this one a lot. You’re running some legacy COM component or a custom app that talks to Outlook or Excel, and boom — 0X80010106. It’s Windows saying “You can’t change the thread’s apartment state after it’s been set.”
Plain English: your app started as single-threaded (STA) but then tried to act multi-threaded (MTA), or vice versa. COM doesn’t let you switch lanes mid-drive.
Let’s fix it.
Fix #1: The 30-Second Fix — Check Your Call Order
Most of the time, this happens because CoInitialize or CoInitializeEx is called after some COM operation already set the apartment. Move that call to the very start of your thread — right after Thread.Start() or Main().
Had a client last month whose print queue software crashed every Friday. Turned out a background thread called CoInitialize inside a loop. Moved it before the loop, problem gone.
// BAD: called after COM work
void BackgroundWorker()
{
// some COM call happens here
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // too late
}
// GOOD: called first
void BackgroundWorker()
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// all COM calls here
}
Fix #2: The 5-Minute Fix — Match Your Threading Model
If Fix #1 didn’t work, you’ve got a mismatch between what the COM object expects and what your thread is providing.
Check the object’s registry:
- Open RegEdit
- Go to
HKEY_CLASSES_ROOT\CLSID\{your-objects-guid}\InprocServer32 - Look for
ThreadingModel. Common values:Apartment,Free,Both,Neutral
Map it:
- Apartment → use
COINIT_APARTMENTTHREADED - Free or Both → use
COINIT_MULTITHREADED
If the registry says Apartment and you passed COINIT_MULTITHREADED, that’s your bug. Flip the flag.
Fix #3: The 15-Minute Fix — Use a Dedicated STA Thread
Sometimes you can’t change the calling code — it’s a third-party DLL or legacy app. In that case, you wrap the COM calls in a thread that’s explicitly STA.
Here’s the pattern in C#:
Thread staThread = new Thread(() =>
{
// This thread will be STA
var result = myComObject.DoSomething();
});
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();
Works every time for Outlook interop or old VB6 components. Just make sure you call SetApartmentState before Start.
When None of That Works
You might be dealing with a buggy COM object that forces MTA even when you set STA. Rare but happens. Try this:
- Use a separate process via
CoCreateInstancewith CLSCTX_LOCAL_SERVER - Or wrap the whole thing in a COM+ application
That’s overkill for 99% of cases. Stick with Fix #1 or #2.
Quick Summary
| Symptom | Likely Cause | Fix |
|---|---|---|
| Error appears on first COM call | CoInitialize called too late | Move to thread start |
| Error with specific DLL | Threading model mismatch | Match registry flag |
| Can’t modify source code | Wrong apartment for object | Use dedicated STA thread |
That’s it. No registry hacks, no reinstalling Windows. Just get your threading model straight and move on.
Was this solution helpful?