pypa/pip · error · SystemError
invalid sysconfig.get_config_var('EXT_SUFFIX')
Error message
invalid sysconfig.get_config_var('EXT_SUFFIX') What it means
Raised as SystemError by _generic_abi (tags.py:495-496) when sysconfig.get_config_var('EXT_SUFFIX') is either not a string or does not start with a '.'. EXT_SUFFIX is the suffix used for CPython extension modules (e.g. '.cpython-310-x86_64-linux-gnu.so'); an unexpected shape means the running interpreter's build configuration is malformed, so the ABI tag cannot be derived.
Solutions
- Verify sysconfig.get_config_var('EXT_SUFFIX') in the failing environment; reinstall or repair the Python build if it is missing/malformed.
- If you control tag generation, pass explicit abis to generic_tags/sys_tags rather than relying on EXT_SUFFIX autodetection.
- For embedded/minimal interpreters, ensure the config vars are populated (rebuild with the normal configuration).
- Catch SystemError around tag generation and fall back to a known ABI list.
Example fix
# before - relies on EXT_SUFFIX autodetection
tags = list(generic_tags()) # SystemError: invalid EXT_SUFFIX
# after - supply the ABI explicitly, or repair the interpreter
import sysconfig
print(sysconfig.get_config_var('EXT_SUFFIX')) # inspect
tags = list(generic_tags(abis=['cp310'])) # bypass EXT_SUFFIX path Defensive patterns
Strategy: try-catch
Validate before calling
import sysconfig
def ext_suffix_ok() -> bool:
s = sysconfig.get_config_var('EXT_SUFFIX')
return isinstance(s, str) and s.startswith('.') Try / catch
try:
tags = list(generic_tags())
except SystemError:
tags = list(generic_tags(abis=[f'cp{sys.version_info.major}{sys.version_info.minor}'])) Prevention
- Inspect EXT_SUFFIX on minimal/embedded interpreters before tag generation.
- Pass explicit abis to bypass EXT_SUFFIX autodetection.
- Repair/reinstall interpreters with malformed sysconfig.
When it happens
Trigger: Running under a minimal/embedded Python build where EXT_SUFFIX is unset (None) or set to a non-dot-prefixed value; a misconfigured PyPy/other interpreter reporting an odd EXT_SUFFIX; a test harness monkeypatching sysconfig to return a non-string.
Common situations: Embedded Python distributions (some app bundles) with stripped sysconfig; broken/abnormal Python installs; running packaging's tag generation in an environment where the interpreter was built without normal config vars; CI on exotic interpreters.
Related errors
- Cannot restore Tag from
- Compressed tag set would generate
- Invalid wheel filename (compressed tag set components must…
- Invalid wheel filename (invalid tag component)
- limit must be non-negative
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/ba29bb313c5d2105.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/tags.py:496
def _generic_abi() -> list[str]:
"""
Return the ABI tag based on EXT_SUFFIX.
"""
# The following are examples of `EXT_SUFFIX`.
# We want to keep the parts which are related to the ABI and remove the
# parts which are related to the platform:
# - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310
# - mac: '.cpython-310-darwin.so' => cp310
# - win: '.cp310-win_amd64.pyd' => cp310
# - win: '.pyd' => cp37 (uses _cpython_abis())
# - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73
# - graalpy: '.graalpy-38-native-x86_64-darwin.dylib'
# => graalpy_38_native
ext_suffix = _get_config_var("EXT_SUFFIX", warn=True)
if not isinstance(ext_suffix, str) or not ext_suffix.startswith("."):
raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')")
parts = ext_suffix.split(".")
if len(parts) < 3:
# CPython3.7 and earlier uses ".pyd" on Windows.
return _cpython_abis(sys.version_info[:2])
soabi = parts[1]
if soabi.startswith("cpython"):
# non-windows
cpython_parts = soabi.split("-")
if len(cpython_parts) < 2 or not cpython_parts[1]:
raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')")
abi = "cp" + cpython_parts[1]
elif soabi.startswith("cp"):
# windows
abi = soabi.split("-")[0]
elif soabi.startswith("pypy"):
abi = "-".join(soabi.split("-")[:2])
elif soabi.startswith("graalpy"):
abi = "-".join(soabi.split("-")[:3])View on GitHub (pinned to f399c37189)