CO_E_NOTPOOLED (0x8004E02C): COM+ component needs object pooling
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.
- Find the CLSID
Look underHKEY_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". - Check InprocServer32
Open theInprocServer32subkey. You'll see aThreadingModelvalue (string REG_SZ). If it's missing or set toApartment, that's your problem. Example of a working entry:
[HKEY_CLASSES_ROOT\CLSID\{your-guid}\InprocServer32]
"ThreadingModel"="Both"
- Set it to "Both" or "Free"
Double-clickThreadingModeland change it toBoth. If the value doesn't exist, right-click, New -> String Value, name itThreadingModel, set data toBoth. "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\CLSIDinstead ofHKEY_CLASSES_ROOT\CLSID, COM+ won't see it for pooling. Move it toHKEY_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?