0X8001013B

CO_E_INCOMPATIBLESTREAMVERSION (0X8001013B) fix — ACL version mismatch explained

Windows Errors Intermediate 👁 1 views 📅 Jun 8, 2026

Happens when a COM object's ACL stream was saved with a newer Windows version and an older version tries to read it. The fix is recompiling or updating the component.

You'll see error CO_E_INCOMPATIBLESTREAMVERSION (0x8001013B) when a COM component — often an ActiveX control, a custom DCOM server, or a legacy shell extension — tries to load security descriptors from a stream and fails. The exact error message reads: "The version of ACL format in the stream is not supported by this implementation of IAccessControl".

I've hit this most often with older Visual Basic 6 COM components that were compiled on Windows XP or Server 2003 and are now being loaded on Windows 10 or Windows 11. Another common trigger: migrating a COM+ application from a 32-bit system to a 64-bit system without recompiling the DLL. The error can also pop up in debugging tools like OleView when you inspect a remote object's security settings.

What's actually happening here

The COM infrastructure uses IAccessControl to manage access rights through a serialized security descriptor stored in a stream. That stream has a header containing a version number. Starting with Windows Vista, Microsoft bumped the ACL stream version from the old Windows 2000/XP format (version 2) to version 3. Version 3 includes new fields for mandatory integrity levels (the Mandatory Integrity Control info that enables UAC).

When a component compiled against an older Windows SDK writes an ACL stream, it stamps version 2 in the header. A component compiled against the newer SDK expects version 3. The IAccessControl::GetAccessRights implementation inside the calling code checks the version — if it doesn't match what it expects, it returns CO_E_INCOMPATIBLESTREAMVERSION. It's not an actual security descriptor corruption; it's a version handshake failure.

The fix

The real fix is to recompile the COM component that implements IAccessControl against the Windows SDK that matches your target OS. Here's the step-by-step.

  1. Identify the culprit component. Use Process Monitor (procmon.exe) from Sysinternals. Filter by the process that throws the error, then look for RegQueryValue or CreateFile operations around the time of failure — the component's DLL path will show up. Or, if you have the error in an event log, note the CLSID from Event ID 1001 in Application logs. Check the registry at HKCR\CLSID\{your-clsid}\InprocServer32 to find the DLL.
  2. Check the build environment of that DLL. Right-click the DLL, go to Properties > Details. Look for "File version" and "Product version". If it was built before 2007 (Windows Vista release), or if the internal version shows a Visual Studio 2003/2005 build, that's the problem.
  3. Recompile the component. Open its source project and set the target SDK to Windows 10 (10.0.19041.0 or later). In Visual Studio, you can do this via Project Properties > General > Windows SDK Version. If the source uses ATL for security descriptor handling, make sure IAccessControl is being implemented with the updated CComAccessControl class from the newer ATL headers.
  4. If you can't recompile (third-party component), you have two options:
    - Run the app in Windows 8 compatibility mode. This tricks the COM layer into handling older ACL streams as version 2. Right-click the executable > Properties > Compatibility > check "Run this program in compatibility mode for" and pick Windows 8.
    - Or, if the component is a COM+ application, you can set the AccessControl property on the application to "None" in Component Services (if your security model allows it). This skips the ACL stream check entirely.
  5. If you wrote the component yourself, check your implementation of IAccessControl::GetAccessRights. You might have hard-coded a version check. Replace it with code that reads the stream version and handles both v2 and v3. Here's a snippet of what that looks like in C++:
HRESULT MyAccessControl::GetAccessRights(
    const GUID* lpguid,
    DWORD dwFlags,
    PACTRL_ACCESSW* ppAccessList,
    TRUSTEE_W** ppOwner,
    TRUSTEE_W** ppGroup)
{
    // Read the header of the security descriptor stream
    ACL_STREAM_HEADER header;
    HRESULT hr = ReadStreamHeader(&header);
    if (FAILED(hr)) return hr;

    // Accept both version 2 and version 3
    if (header.dwVersion != 2 && header.dwVersion != 3)
        return CO_E_INCOMPATIBLESTREAMVERSION;

    // Proceed with deserialization
    ...
}

If you handle both versions, your component will work on Windows 7 through Windows 11 without recompiling for each OS.

If it still fails

Check three things:

  • DLL registration. The component must be registered with the correct threading model. Run regsvr32 yourcomponent.dll from an elevated command prompt. If you get a different error, the component might be corrupted or a dependency (like MSVCRT) is missing.
  • 64-bit vs 32-bit mismatch. If your app is 64-bit, the COM component must also be 64-bit. A 32-bit DLL calling IAccessControl on a 64-bit process can produce this error due to the COM marshaller failing to negotiate the stream version across bitness. Fix: use a 64-bit build of the component, or run the app as a 32-bit process (disable the "Prefer 32-bit" flag in the project settings).
  • Antivirus or security software. Some endpoint security tools intercept COM security calls and inject their own IAccessControl implementation. Temporarily disable the software to see if the error disappears. If so, add an exception for the application.

Was this solution helpful?