Skip to content

Windows wheel vendors combase.dll (a system KnownDLL) → ImportError WinError 1114 #1640

Description

@samy-noh

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:

  1. copied the build machine's combase.dll into
    pact_python_ffi.libs/combase-<hash>.dll, and
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions