ModuleNotFoundError
No module named 'PIL'
Cause: Pillow is not installed in the active Python environment (or a different interpreter is being used).
Fix: Install the package named Pillow; it imports as PIL.
python -m pip install --upgrade Pillow
# then: from PIL import Image
Full guide: No module named 'PIL': every cause and fix.
OSError
cannot identify image file
Cause: The file is not an image Pillow can read. Pillow ignores the extension and checks the content, which is often an HTML error page, an empty download, HEIC (needs pillow-heif) or SVG.
Fix: Look at the first bytes to see what the file really is.
with open("file.jpg", "rb") as f:
print(f.read(16)) # b'\xff\xd8\xff' = JPEG, b'<!DOCTYPE html' = an error page
Full guide: cannot identify image file: causes and a diagnostic script.
OSError
image file is truncated
Cause: The image is incomplete or partially downloaded. Pillow refuses to load it by default.
Fix: Allow truncated images to load (only for trusted input), or re-download the file.
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
Full guide: image file is truncated: causes, detection and recovery.
OSError
cannot write mode RGBA as JPEG
Cause: JPEG has no alpha channel, but the image is in RGBA mode.
Fix: Flatten to RGB (or composite onto a background) before saving.
img.convert("RGB").save("output.jpg", quality=95)
Plain convert("RGB") turns transparent areas black. To flatten onto white instead, see the RGBA to JPEG fixer.
OSError
cannot write mode P as JPEG
Cause: A palette-mode (P) image cannot be saved directly as JPEG.
Fix: Convert to RGB first.
img.convert("RGB").save("output.jpg")
Full guide: cannot write mode F / P / LA / I;16 / CMYK, with a format-by-mode table.
AttributeError
module 'PIL.Image' has no attribute 'ANTIALIAS'
Cause: Image.ANTIALIAS was deprecated in Pillow 9.1 and removed in Pillow 10.0 (July 2023).
Fix: Use Image.LANCZOS: the same filter, available in every Pillow version since 2.7.
img.resize((400, 300), Image.LANCZOS)
Full guide: ANTIALIAS removed: replacements and fixing third-party libraries.
ImportError
cannot import name '_imaging' from 'PIL'
Cause: The native C extension was built against a different Python version or CPU architecture (common on Apple Silicon).
Fix: Reinstall a clean pre-built wheel.
python -m pip uninstall -y Pillow
python -m pip install --upgrade --no-cache-dir Pillow
DecompressionBombWarning
Image may be a decompression bomb
Cause: The image is larger than Pillow's safety limit: a warning above 89,478,485 pixels and a DecompressionBombError above 178,956,970. The limit guards against denial-of-service attacks.
Fix: Raise or disable the limit for trusted sources only.
Image.MAX_IMAGE_PIXELS = 500_000_000 # or None to disable
Full guide: DecompressionBombWarning: the two limits and safe ways around them.
MemoryError
Out of memory processing large images
Cause: Large images are decoded fully into RAM before processing.
Fix: Use JPEG draft mode, downscale early, or process in tiles.
img = Image.open("huge.jpg")
img.draft("RGB", (800, 600)) # JPEG only
img.load()
Orientation
Image appears rotated after opening
Cause: Cameras store rotation in the EXIF Orientation tag; Pillow does not auto-rotate on open.
Fix: Apply the EXIF transpose.
from PIL import ImageOps
img = ImageOps.exif_transpose(img)
ValueError
images do not match
Cause: ImageChops operations require both images to have identical size and mode.
Fix: Normalise size and mode before combining.
b = b.convert(a.mode).resize(a.size)
result = ImageChops.difference(a, b)
TypeError
'Image' object is not subscriptable / cannot slice
Cause: Treating a Pillow Image like a NumPy array.
Fix: Convert explicitly, or use getpixel().
import numpy as np
arr = np.array(img) # to array
crop = img.crop((0, 0, 100, 100))
PermissionError
Permission denied when saving
Cause: The output file is open in another program, or the target directory is not writable.
Fix: Close the file, or write to a different path / ensure the directory exists.
import os
os.makedirs("out", exist_ok=True)
img.save("out/result.png")
AttributeError
'ImageDraw' object has no attribute 'textsize'
Cause: textsize(), multiline_textsize() and FreeTypeFont.getsize() were removed in Pillow 10.0.
Fix: Measure with textbbox() (or textlength() for the width).
left, top, right, bottom = draw.textbbox((0, 0), text, font=font)
w, h = right - left, bottom - top
Full guide: textsize removed: replacements and the centring bug.
OSError
cannot open resource (ImageFont.truetype)
Cause: FreeType cannot find the font file. Names like "arial.ttf" only resolve on Windows, and the lookup is case-sensitive on macOS and Linux.
Fix: Pass a full path, or ship the font with your code.
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 40)
# or, Pillow 10.1+: ImageFont.load_default(size=40)
Full guide: cannot open resource: where Pillow looks for fonts.
ImportError
cannot import name 'ImageDraw' from 'PIL'
Cause: Usually a file or folder named PIL (e.g. PIL.py) in your project is shadowing the real package; the error message shows its path. Also seen with a broken or partial install.
Fix: Rename your PIL.py, or reinstall Pillow. Then import submodules explicitly.
from PIL import Image, ImageDraw, ImageFont