Windows wheel vendors combase.dll (a system KnownDLL) → ImportError: DLL load failed while importing ffi (WinError 1114) on some Windows builds
Summary
The Windows wheel of pact-python-ffi bundles a private copy of combase.dll
into pact_python_ffi.libs/ and rewrites the FFI extension to import that
mangled copy instead of the system DLL. combase.dll is a Windows system
KnownDLL that is tightly coupled to the OS build. On a machine whose Windows
build differs from the one the wheel was built on, the vendored copy fails its
DLL initialization routine (ERROR_DLL_INIT_FAILED, 1114), which aborts
import pact entirely — and, in a pytest run, aborts collection of the whole
test suite.
Affected versions
pact-python 3.4.0 → depends on pact-python-ffi ~= 0.5.0
pact-python-ffi 0.5.3.0 and 0.5.4.0 — both ship the same vendored
combase (identical hash combase-bd276885ec4ae79f1e32b9da095d8064.dll)
pact-python-ffi 0.4.x is not affected (no vendored combase)
Environment
- Windows 11, build 10.0.26200 (x64)
- CPython 3.14 (also reproduces conceptually on any interpreter — this is a
native-DLL loading issue, not a Python-version issue)
Symptom
ImportError: DLL load failed while importing ffi: A dynamic link library (DLL)
initialization routine failed.
Traceback ends at:
pact/pact.py -> import pact_ffi
pact_ffi/__init__.py -> from pact_ffi.ffi import ffi, lib
OSError.winerror == 1114 (ERROR_DLL_INIT_FAILED).
Root cause
The wheel was repaired with delvewheel 1.12.0 (visible from the
_delvewheel_patch_1_12_0 shim in pact_ffi/__init__.py). The Rust core
pact_ffi.dll depends on combase.dll (COM). delvewheel 1.12.0 did not yet
exclude combase.dll from vendoring, so it:
- copied the build machine's
combase.dll into
pact_python_ffi.libs/combase-<hash>.dll, and
- patched
pact_python_ffi.libs/pact_ffi-<hash>.dll's import table to import
combase-<hash>.dll instead of combase.dll.
Because the import no longer uses the exact name combase.dll, the Windows
KnownDLL redirection (which would normally force-load the OS's own
System32\combase.dll) is bypassed, and the private, build-coupled copy is
loaded instead. On a Windows build that differs from the build runner's, that
copy's DllMain fails → 1114.
combase.dll is registered under
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs — it is not a
DLL that should ever be vendored.
Proof
In the installed package (site-packages/pact_python_ffi.libs/):
import ctypes
# vendored, mangled copy — fails:
ctypes.CDLL("combase-bd276885ec4ae79f1e32b9da095d8064.dll")
# -> OSError [WinError 1114] A dynamic link library (DLL) initialization routine failed
# the OS's own combase — loads fine:
ctypes.CDLL(r"C:\Windows\System32\combase.dll") # OK
Patching the mangled pact_ffi-<hash>.dll's import name back from
combase-<hash>.dll to combase.dll (so KnownDLL redirection applies) makes
import pact succeed:
>>> import pact_ffi.ffi # OK
>>> from pact import Pact, match # OK
Fix
This is already solved on the delvewheel side:
delvewheel 1.12.1 (6 May 2026): "Add combase.dll to DLL exclusion list."
Rebuilding pact-python-ffi with delvewheel ≥ 1.12.1 (1.13.0 also works)
stops combase from being vendored, so the system KnownDLL is used and the wheel
loads on any Windows build.
Alternatively, keep the current delvewheel but add --exclude combase.dll to
the repair command.
Impact
import pact fails outright on affected Windows builds.
- Under pytest, because the import happens at module import time, a single
contract-test module aborts collection of the entire suite (not just that
test) with an error, even when the test is deselected by marker.
Windows wheel vendors
combase.dll(a system KnownDLL) →ImportError: DLL load failed while importing ffi(WinError 1114) on some Windows buildsSummary
The Windows wheel of
pact-python-ffibundles a private copy ofcombase.dllinto
pact_python_ffi.libs/and rewrites the FFI extension to import thatmangled copy instead of the system DLL.
combase.dllis a Windows systemKnownDLL that is tightly coupled to the OS build. On a machine whose Windows
build differs from the one the wheel was built on, the vendored copy fails its
DLL initialization routine (
ERROR_DLL_INIT_FAILED, 1114), which abortsimport pactentirely — and, in a pytest run, aborts collection of the wholetest suite.
Affected versions
pact-python3.4.0 → depends onpact-python-ffi ~= 0.5.0pact-python-ffi0.5.3.0 and 0.5.4.0 — both ship the same vendoredcombase (identical hash
combase-bd276885ec4ae79f1e32b9da095d8064.dll)pact-python-ffi0.4.x is not affected (no vendored combase)Environment
native-DLL loading issue, not a Python-version issue)
Symptom
Traceback ends at:
OSError.winerror == 1114(ERROR_DLL_INIT_FAILED).Root cause
The wheel was repaired with delvewheel 1.12.0 (visible from the
_delvewheel_patch_1_12_0shim inpact_ffi/__init__.py). The Rust corepact_ffi.dlldepends oncombase.dll(COM). delvewheel 1.12.0 did not yetexclude
combase.dllfrom vendoring, so it:combase.dllintopact_python_ffi.libs/combase-<hash>.dll, andpact_python_ffi.libs/pact_ffi-<hash>.dll's import table to importcombase-<hash>.dllinstead ofcombase.dll.Because the import no longer uses the exact name
combase.dll, the WindowsKnownDLL redirection (which would normally force-load the OS's own
System32\combase.dll) is bypassed, and the private, build-coupled copy isloaded instead. On a Windows build that differs from the build runner's, that
copy's
DllMainfails → 1114.combase.dllis registered underHKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs— it is not aDLL that should ever be vendored.
Proof
In the installed package (
site-packages/pact_python_ffi.libs/):Patching the mangled
pact_ffi-<hash>.dll's import name back fromcombase-<hash>.dlltocombase.dll(so KnownDLL redirection applies) makesimport pactsucceed:Fix
This is already solved on the delvewheel side:
Rebuilding
pact-python-ffiwith delvewheel ≥ 1.12.1 (1.13.0 also works)stops combase from being vendored, so the system KnownDLL is used and the wheel
loads on any Windows build.
Alternatively, keep the current delvewheel but add
--exclude combase.dlltothe repair command.
Impact
import pactfails outright on affected Windows builds.contract-test module aborts collection of the entire suite (not just that
test) with an error, even when the test is deselected by marker.