Reinstall Pillow for the interpreter you are running: python -m pip install --force-reinstall --upgrade pillow.
Then check that python -c "import PIL; print(PIL.__file__)" points into that interpreter's
site-packages, not into your project folder. For Lambda, Docker or a copied site-packages, install
Pillow on (or for) the platform where the code runs.
The error
To reproduce it, we put a copy of Pillow next to the script with the compiled extension missing, like a vendored copy made on another machine:
from PIL import Image
File "/home/you/project/PIL/Image.py", line 95, in <module>
from . import _imaging as core
ImportError: cannot import name '_imaging' from 'PIL' (/home/you/project/PIL/__init__.py)
Notice the path in the message: from 'PIL' (/home/you/project/PIL/__init__.py). It tells you which
PIL Python found. If that is not inside your environment's site-packages, a local folder is
shadowing the real install:
import PIL
print(PIL.__file__)
print(PIL.__version__)
/home/you/project/PIL/__init__.py
12.3.0
Even PIL.__version__ works, because it does not need the compiled part. Delete or rename the stray folder
(often a PIL directory copied in by hand, or left by a build tool) and the installed Pillow is used again.
The _imaging extension was built for another version of Pillow
Pillow checks that its Python files and its compiled core come from the same release. They stop matching when an upgrade
is interrupted, when two installs overlap in one folder, or when pip and conda both manage Pillow
in the same environment. We faked a half-upgraded install by editing the version file:
from PIL import Image
ImportError: The _imaging extension was built for another version of Pillow or PIL:
Core version: 12.3.0
Pillow version: 11.0.0
Reinstall cleanly: python -m pip uninstall -y pillow (repeat until it says Pillow is not installed), then
python -m pip install pillow. In a conda environment, use conda install pillow for both steps instead
of mixing the two tools.
libtiff-…so: cannot open shared object file (Lambda, Docker, zipped deployments)
On Linux, the Pillow wheel keeps the libraries it bundles (libjpeg, libtiff, libwebp…) in a separate
pillow.libs folder beside PIL. Copy only PIL, as hand-made AWS Lambda layers and
some Dockerfiles do, and the core cannot load:
from PIL import Image
ImportError: libtiff-fc87e79d.so.6.2.0: cannot open shared object file: No such file or directory
The same happens when the package was installed on macOS or Windows and uploaded to Linux. Build the deployment package with the target platform's wheel and ship the whole folder:
pip install pillow --platform manylinux_2_28_x86_64 --only-binary=:all: --python-version 3.13 --target package/
Use manylinux_2_28_aarch64 for ARM (Graviton) functions, and the Python version of your runtime. The
manylinux2014 tag found in many older guides no longer works: we checked, and pip finds no Pillow 12.3 wheel for
it, because current Pillow wheels target glibc 2.28 and newer.
Windows: DLL load failed while importing _imaging
This is the Windows form of the same failure. Typical causes, in the order we would check them:
- Mixed installers: Pillow from
pipon top of Pillow fromconda(or the reverse) in one environment. Reinstall with one tool only. - A copied environment: a virtual environment or
site-packagesmoved from another PC or another Python version. Recreate it withpython -m venvand reinstall. - A wheel for another interpreter: installed with one Python's pip, run with another (32-bit vs 64-bit,
or 3.12 vs 3.13). Always install with
python -m pipusing the samepythonyou run. - A conflicting DLL on
PATH: an oldlibjpegorzlibDLL from other software, loaded first. Running from a clean prompt, or with a fresh environment, confirms it.
_imagingft: fonts fail, everything else works
_imagingft is the separate extension that wraps FreeType. If only it is missing or broken, you can open, edit
and save images, but text with TrueType fonts fails, and only when you load a font:
from PIL import Image, ImageDraw, ImageFont
print("imported fine")
font = ImageFont.truetype("DejaVuSans.ttf", 40)
ImportError: cannot import name '_imagingft' from 'PIL' (/home/you/project/PIL/__init__.py). Did you mean: '_imaging'?
Older Pillow versions phrased this as The _imagingft C module is not installed. With official wheels it does
not happen; it means Pillow was built from source without the FreeType headers. Install a wheel (upgrade pip first, so it can
find one for your platform), or install FreeType's development package before building.
decoder jpeg not available, and checking what your Pillow supports
OSError: decoder jpeg not available (or zip, for PNG) comes from the same kind of source build:
Pillow compiled without libjpeg or zlib. The official wheels include them. To see what an installation supports:
from PIL import features
for name in ["jpg", "zlib", "libtiff", "freetype2", "webp", "avif", "littlecms2", "raqm"]:
print(f"{name:<11}", features.check(name), features.version(name) or "")
jpg True 6.2
zlib True 1.3
libtiff True 4.7.1
freetype2 True 2.14.3
webp True 1.6.0
avif True 1.4.2
littlecms2 True 2.19
raqm True 0.10.5
python -m PIL.report prints the full report, including the Python and Pillow paths it is using, which is the
first thing to paste into a bug report. Run it from a folder without a stray PIL directory, or it reports on
that copy instead.
Related
The outputs and images on this page are the real results of running every example with Pillow 12.3.0 on Python 3.13 (Linux) on 2026-10-15. Every example is also re-run automatically on macOS (Darwin 25.6.0, Pillow 12.3.0), Linux (Linux 6.17.0-1022-azure, Pillow 12.3.0), Windows (Windows 2025Server, Pillow 12.3.0); the line under each example shows the result per operating system. The DejaVu Sans font files sit next to each script so font examples behave the same everywhere. Sample photos: NASA/Sam Lott, public domain. Spotted something wrong? Tell us.