Quick answer: The activation context you're trying to deactivate wasn't activated on this thread. The fix is almost always a bad assembly manifest, a mismatched DLL/Application manifest pair, or COM code calling DeactivateActCtx from a thread that never activated it.
I know this error is infuriating. It shows up as a hard crash with no useful stack, often in an app that worked fine yesterday. The trigger is usually a third-party DLL that shipped with its own embedded manifest (say, a newer version of a C++ runtime redistributable), and now the loader is trying to deactivate an activation context that was never bound to the calling thread. I first hit this on a Win32 app pulling in a vendor's OCR library after a silent auto-update. The app itself hadn't changed. The library had. That's the pattern more often than not—an update somewhere else broke the SxS chain.
SxS (side-by-side) uses a per-thread activation stack. ActivateActCtx pushes a cookie, DeactivateActCtx pops it. If you call Deactivate with a cookie that belongs to a different thread, or you call it twice, or the stack got unbalanced by an earlier failure, you get 0xC0150010. The error code is really the loader telling you: your activation bookkeeping is off. Below are the fixes in the order I'd try them.
Fix 1: Isolate the offending module
- Open Event Viewer (
eventvwr.msc) and go to Windows Logs → Application. Look for a SideBySide source entry near the crash timestamp. It names the failing assembly and often the DLL that requested it. - Note the exact assembly name and version—for example,
Microsoft.VC90.MFC,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8". - Open an elevated Command Prompt and run:
These replace corrupt SxS manifests insfc /scannow dism /online /cleanup-image /restorehealthC:\Windows\winsxs. If the SxS entry in Event Viewer points to a Microsoft assembly, this often clears it. - Reboot and relaunch the app. If the error is gone, the manifest store was the problem.
Fix 2: Repair the application's manifest
If SFC didn't help, the broken manifest is probably the app's own. Open the EXE in a resource editor (I use Resource Hacker) and check RT_MANIFEST. Two things kill you here: a dependency listed with one processor architecture while the EXE is another (x86 vs amd64), or a private assembly in the app folder whose version doesn't match the manifest entry.
Compare the manifest dependency line against what's actually in the app's install folder:
dumpbin /manifest path\to\yourapp.exe
If the manifest demands version="9.0.21022.8" but your Microsoft.VC90.CRT folder contains 9.0.30729.1, that's your culprit. Replace the CRT folder with the matching build, or update the manifest to match what's shipped. Don't mix—the loader won't reconcile them for you.
Fix 3: Fix the thread-affinity bug (devs only)
If you wrote the code and the error is intermittent, you're almost certainly mismanaging the activation context across threads. ActivateActCtx and DeactivateActCtx must be paired on the same thread, with the same cookie, in LIFO order. A common mistake is activating on a UI thread, then calling the worker function from a thread-pool callback and deactivating there. The cookie is thread-local—it won't resolve.
// Wrong: ctx activated on caller thread, deactivated on pool thread
ActivateActCtx(hCtx, &cookie);
QueueUserWorkItem(Worker, &cookie); // boom
// Right: activate inside the worker, deactivate inside the worker
void Worker(PVOID) {
ULONG_PTR cookie;
ActivateActCtx(hCtx, &cookie);
// ... work ...
DeactivateActCtx(0, cookie);
}
Also check COM: if a COM object activates a context in DllGetClassObject and deactivates in Release, but those run on different apartments, you'll hit 0xC0150010 every time.
Alternative fixes if the above don't work
- Reinstall the Visual C++ redistributable. Uninstall every version from Programs and Features, then reinstall the exact ones your app needs. Half-installed redists are a classic cause.
- Disable the problematic manifest temporarily by renaming the app's external
.manifestfile (only if it has one separate from the embedded one). This tells you whether the manifest itself is the problem or something deeper. - Run under Application Verifier. Enable the Basics → Activation Context checks on the EXE. It'll break at the exact line where the imbalance happens. Takes 20 minutes and saves hours.
- Check for duplicate DLLs. A rogue copy of
comctl32.dllor an old MFC DLL sitting in the app folder will shadow the system one and break the SxS chain. Usewhere /R "C:\Program Files\YourApp" *.dlland compare against System32.
Prevention tip
Never ship an app with a private assembly folder unless you're pinning the exact version. If you must, add a build-time check that verifies every manifest dependency resolves to a file present in the deployment. I've seen teams waste days on this because a CI job dropped an old Microsoft.VC90.CRT folder into the installer while the manifest asked for a newer one. One validation step in your build pipeline would've caught it. Also: keep your redistributables in lockstep with the SDK you compiled against. Drift there is what creates 0xC0150010 in the wild.