0X8004E02C

CO_E_NOTPOOLED (0x8004E02C): COM+ component needs object pooling

Windows Errors Intermediate 👁 0 views 📅 May 27, 2026

You get this when a COM+ component marked for pooling can't pool. The component's CLSID lacks the right registry flags. Here's why and how to fix it.

You're building or running a COM+ component — maybe a custom .NET serviced component, maybe an old ATL object — and you've enabled object pooling in the Component Services snap-in. But when your client code tries to create an instance, it slams into error 0x8004E02C with the message "The COM+ component you created must use object pooling to work". This typically hits right after you call CoCreateInstance or new on the COM+ object, often in a high-throughput server app like an IIS worker process or a Windows Service that expects pooled objects for performance.

What's actually happening here

The error isn't saying "you forgot to enable pooling." It's saying the opposite: COM+ sees that the component is marked as requiring pooling (usually via the COM+ catalog), but the underlying COM class registration in the registry doesn't have the proper flags to support it. COM+ object pooling works by asking the COM runtime to hold a pool of pre-created instances. But if the CLSID's InprocServer32 key is missing the ThreadingModel value (or has the wrong one), COM+ can't safely pool the objects and throws this error.

The real trigger is a mismatch between the COM+ application's pooling settings and the component's threading model. For pooling to work, the component must use the "Both" or "Free" threading model. If it's set to "Apartment" or missing entirely, COM+ refuses to pool because apartment-threaded objects can't be reused across threads without expensive marshaling — which defeats the purpose.

The fix: set the right threading model in the registry

Skip the Component Services GUI for this — it won't show you the raw registry values. Open Regedit and go straight to the CLSID. You'll need the component's GUID.

  1. Find the CLSID
    Look under HKEY_CLASSES_ROOT\CLSID\{your-guid}. If you don't know the GUID, check the Component Services snap-in: right-click the component, Properties, General tab — it's listed as "CLSID".
  2. Check InprocServer32
    Open the InprocServer32 subkey. You'll see a ThreadingModel value (string REG_SZ). If it's missing or set to Apartment, that's your problem. Example of a working entry:
[HKEY_CLASSES_ROOT\CLSID\{your-guid}\InprocServer32]
"ThreadingModel"="Both"
  1. Set it to "Both" or "Free"
    Double-click ThreadingModel and change it to Both. If the value doesn't exist, right-click, New -> String Value, name it ThreadingModel, set data to Both. "Both" works for almost all components — it means the object can be called from any apartment without marshaling. "Free" is also fine but stricter. Avoid "Apartment"—it breaks pooling.

After changing the registry, restart the COM+ application (right-click it in Component Services and choose Shut Down, then start it again). Or recycle the host process if it's IIS: run iisreset or recycle the app pool.

If the component is a .NET serviced component

If you wrote the component in C# or VB.NET with System.EnterpriseServices, you probably set [ObjectPooling] in code. That's fine — but the assembly's threading model defaults to "Apartment" unless you specify otherwise. Add this attribute to the component class:

[Synchronization(SynchronizationOption.Required)]
[ObjectPooling(MinPoolSize=2, MaxPoolSize=10, CreationTimeout=2000)]
public class MyPooledComponent : ServicedComponent
{ ... }

Then re-register the assembly with regsvcs. The Synchronization attribute forces COM+ to use the "Both" model internally.

What to check if it still fails

  • 32-bit vs 64-bit mismatch: If your component is compiled for 32-bit but running on a 64-bit OS under a 64-bit COM+ host, you'll get this error. Check the Component Services application's "Advanced" tab — enable "Allow 32-bit components" if available.
  • COM+ application identity: Pooling requires the COM+ application to run under a user account that has the "Impersonate a client after authentication" privilege (Local Security Policy). This is often missing for Network Service or custom accounts.
  • Registration in the wrong hive: If the component is registered under HKEY_CURRENT_USER\CLSID instead of HKEY_CLASSES_ROOT\CLSID, COM+ won't see it for pooling. Move it to HKEY_CLASSES_ROOT.
  • Check Event Viewer: Look under Windows Logs -> Application for COM+ warnings with source "COM+" — they often contain the exact CLSID and a reason like "threading model not compatible."

If nothing works, try removing the component from the COM+ application, deleting and recreating the application, then re-adding the component. That forces COM+ to re-read the registry values cleanly.

Was this solution helpful?