PIL DecompressionBombError: Image size exceeds limit (tested)

PIL.Image.DecompressionBombError: Image size (... pixels) exceeds limit of 178956970 pixels is raised by Image.open() when an image declares more than twice Image.MAX_IMAGE_PIXELS (89,478,485 by default); between 1× and 2× you only get DecompressionBombWarning. For trusted files set Image.MAX_IMAGE_PIXELS higher (or None); for uploads keep it and reject.

Test files were made with Image.new("1", (20000, 20000)).save("/tmp/huge.png") (400 million pixels) and the same at 10000×10000 (100 million pixels).

1. The error

import os
from PIL import Image
print(os.path.getsize("/tmp/huge.png"), "bytes on disk")
img = Image.open("/tmp/huge.png")

Output:

48610 bytes on disk
Traceback (most recent call last):
  File "/w/b1.py", line 4, in <module>
    img = Image.open("/tmp/huge.png")
  File "/usr/local/lib/python3.14/site-packages/PIL/Image.py", line 3704, in open
    im = _open_core(fp, filename, prefix, formats)
  File "/usr/local/lib/python3.14/site-packages/PIL/Image.py", line 3693, in _open_core
    _decompression_bomb_check(im.size)
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/usr/local/lib/python3.14/site-packages/PIL/Image.py", line 3590, in _decompression_bomb_check
    raise DecompressionBombError(msg)
PIL.Image.DecompressionBombError: Image size (400000000 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack.

A 48 KB PNG declares 400 million pixels. Pillow checks the declared size in Image.open(), before decoding anything, and refuses images larger than twice Image.MAX_IMAGE_PIXELS (2 × 89,478,485 = 178,956,970). That protects servers that accept uploads: a tiny file can expand to gigabytes of RAM when decoded.

2. Between 1× and 2× the limit it is only a warning

from PIL import Image
print("MAX_IMAGE_PIXELS =", Image.MAX_IMAGE_PIXELS)
img = Image.open("/tmp/big.png")        # 100,000,000 pixels: over the limit, under 2x
print(img.size, "opened, only a warning")

Output:

MAX_IMAGE_PIXELS = 89478485
/usr/local/lib/python3.14/site-packages/PIL/Image.py:3593: DecompressionBombWarning: Image size (100000000 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
  warnings.warn(
(10000, 10000) opened, only a warning

At 100 million pixels you get DecompressionBombWarning and the image opens. The default limit of 89,478,485 pixels is about a 9459×9459 image, so large photos, scans, maps and satellite tiles hit it routinely.

3. Fix for trusted files: raise or disable the limit

from PIL import Image
# trusted input only: raise the limit to what you actually expect
Image.MAX_IMAGE_PIXELS = 500_000_000
img = Image.open("/tmp/huge.png")
print(img.size, img.mode)
Image.MAX_IMAGE_PIXELS = None       # disables the check entirely
img = Image.open("/tmp/huge.png")
print("limit disabled:", img.size)

Output:

(20000, 20000) 1
limit disabled: (20000, 20000)

Set Image.MAX_IMAGE_PIXELS once, before opening, to the largest size you expect. None turns the check off; only do that for files you created or fully trust, and make sure the machine has the RAM (the 400-million-pixel image needs about 1.2 GB once converted to RGB).

4. For uploads: turn the warning into an error and reject

import warnings
from PIL import Image

def open_untrusted(path):
    with warnings.catch_warnings():
        warnings.simplefilter("error", Image.DecompressionBombWarning)   # warning -> exception
        try:
            return Image.open(path)
        except (Image.DecompressionBombError, Image.DecompressionBombWarning) as e:
            raise ValueError(f"rejected {path}: {e}") from None

for p in ("/tmp/huge.png", "/tmp/big.png"):
    try:
        open_untrusted(p)
    except ValueError as e:
        print(str(e)[:120])
print(issubclass(Image.DecompressionBombError, Exception), Image.DecompressionBombWarning.__mro__[1].__name__)

Output:

rejected /tmp/huge.png: Image size (400000000 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS
rejected /tmp/big.png: Image size (100000000 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS a
True RuntimeWarning

For untrusted input keep the limit (or lower it) and also treat the warning as an error, so both sizes are rejected with a clean message instead of being decoded. DecompressionBombError is a regular Exception; DecompressionBombWarning is a RuntimeWarning, so it is not catchable with except unless you turn it into an error as above.

Related: numpy read-only arrays from PIL images · [Errno 28] No space left on device.

Frequently asked questions

How do I fix DecompressionBombError?

For trusted images set Image.MAX_IMAGE_PIXELS = <a larger number> (or None) before Image.open(). For user uploads, keep the limit and reject the file.

What is the default MAX_IMAGE_PIXELS?

89,478,485 pixels in Pillow 13.0.0. Above that you get DecompressionBombWarning; above twice that (178,956,970) DecompressionBombError.

How do I catch DecompressionBombWarning?

It is a RuntimeWarning, not an exception. Use warnings.simplefilter('error', Image.DecompressionBombWarning) inside warnings.catch_warnings() and then except it.

Written with AI assistance. Measured on 2026-10-23 with Pillow 13.0.0 and Python 3.14.7 (python:3-alpine in Docker). Each block was run verbatim and the output pasted unedited. PlainInspect is our extension; Python and Pillow are free.