You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
File "<redacted>/venv/lib/python3.14/site-packages/PIL/Image.py", line 94, in <module>
from . import _imaging as core
ImportError: libz.so.1: cannot open shared object file: No such file or directory
What are your OS, Python and Pillow versions?
OS: Linux (nixos but also got the error in github actions)
Python: 3.14
Pillow: 13.0
from . import _imaging as core
ImportError: libz.so.1: cannot open shared object file: No such file or directory
which depends on zlib. That causes python (from nix) to load the libz from the nix store, that way when pillow core tries to load libz.so, it is already loaded and everything works fine. In 13 that import was moved into functions, so the png implementation is getting called before and that causes the issue.
Apparently due to auditwheel 5.x (the aforementioned issue), between Pillow 9.0 and 9.1 (2022), Pillow stopped shipping a libz wheel on Linux. zlib-ng was added to the build in #8500 (2024), but due to that auditwheel policy it's not shipped on Linux at all. The system libz, whether or not it ends up being zlib-ng or just plain zlib, gets used? (That's touched upon in #5986.)
So, basically, looks like currently:
Linux CI is building zlib-ng to build and dynamically link against, to throw it away during auditwheel repair
CI-built Linux wheels talk about a zlib_ng feature (and version), but that may not be true at all
the 11.1.0 "zlib-ng in wheels" changelog note is only relevant for macOS and Windows wheels
AISI, to actually include zlib-ng in Linux wheels, if that's desired, we'd need to build it with a different soname and also ZLIB_SYMBOL_PREFIX to avoid clashing against another libz that might be loaded from the system (or Nix stores).
And also, by my reasoning, looks like Pillow's manylinux wheels have basically just accidentally worked on NixOS at all since the NixOS build of Python has a zlib Python standard library module that links to the NixOS-stored libz.so.1, so once import zlib is run, those libz symbols are available.
Apparently a NixOS-user-side fix is nix-ld (I didn't look any further into that).
A fix on Pillow's side is to explicitly import zlib in, say, Image.py:
try:
# Try to ensure libz symbols are loaded, since Pillow extension modules# require it. Pillow's Linux wheels expect the system to provide libz# (see https://github.com/pypa/auditwheel/issues/152) instead of bundling it.# On OSes like NixOS libz may not be on the library default search path,# so the Pillow wheel will not be able to automatically load it.## However, the Python standard library zlib module will have been configured# to link correctly against libz, so importing it should provide the symbols.importzlib# noqa: F401exceptImportError:
pass
I know it affect mostly (only?) nix, but fixing it is a single line (try ... except is not even need there) and allows python to resolve the dynamic library instead of leaving it to C.
Activity
leiserfg commentedon Nov 9, 2026
I found that if I do
import zlibfirst it loads the lib and does not fail.hugovk commentedon Nov 9, 2026
How did you install Pillow? Is it from a wheel or built from source?
You say you also get it in GitHub Actions, can you share a link to a failing run?
If it's private, could you strip it down to a minimal public repro showing how you install and run Pillow?
leiserfg commentedon Nov 9, 2026
It happens 'cause I use nix. The previous version used to import zlib before importing core, that's why it didn't fail, as that fixed the path.
[-]13.0 complains about missing libz[/-][+]13.0.0 complains about missing libz[/+]radarhere commentedon Nov 10, 2026
It's likely irrelevant, but looking at Pillow 12.3.0, I can't see this. Could you be more specific?
leiserfg commentedon Nov 10, 2026
Yes, it is indeed the case, Pillow used to
import tempfilePillow/src/PIL/Image.py
Line 39 in bb1d8e8
zlib. That causes python (from nix) to load the libz from the nix store, that way when pillow core tries to loadlibz.so, it is already loaded and everything works fine. In 13 that import was moved into functions, so the png implementation is getting called before and that causes the issue.akx commentedon Nov 10, 2026
Yep,
python -v(import tracing) shows 12.3.0 used to implicitly import zlib and 13.0 doesn't:akx commentedon Nov 10, 2026
Sleuthing seems to point at pypa/auditwheel#152 and #5986 as relevant..
Apparently due to auditwheel 5.x (the aforementioned issue), between Pillow 9.0 and 9.1 (2022), Pillow stopped shipping a libz wheel on Linux. zlib-ng was added to the build in #8500 (2024), but due to that auditwheel policy it's not shipped on Linux at all. The system libz, whether or not it ends up being zlib-ng or just plain zlib, gets used? (That's touched upon in #5986.)
So, basically, looks like currently:
zlib_ngfeature (and version), but that may not be true at allAISI, to actually include zlib-ng in Linux wheels, if that's desired, we'd need to build it with a different soname and also ZLIB_SYMBOL_PREFIX to avoid clashing against another libz that might be loaded from the system (or Nix stores).
akx commentedon Nov 10, 2026
And also, by my reasoning, looks like Pillow's manylinux wheels have basically just accidentally worked on NixOS at all since the NixOS build of Python has a
zlibPython standard library module that links to the NixOS-storedlibz.so.1, so onceimport zlibis run, thoselibzsymbols are available.Apparently a NixOS-user-side fix is nix-ld (I didn't look any further into that).
A fix on Pillow's side is to explicitly import zlib in, say,
Image.py:leiserfg commentedon Nov 10, 2026
I know it affect mostly (only?) nix, but fixing it is a single line (
try ... exceptis not even need there) and allows python to resolve the dynamic library instead of leaving it to C.hugovk commentedon Nov 10, 2026
zlibis an optional module, so not guaranteed for all distros.https://docs.python.org/3/library/zlib.html
It would be good if zlib-ng was used in the Linux wheels to get the speedup.
pypa/auditwheel#613 (comment) says building zlib-ng as a static library works.
radarhere commentedon Nov 12, 2026
So when pypa/auditwheel#694 is merged and released, this will be fixed?