matplotlib/matplotlib · error · RuntimeError
Unknown image mode
Error message
Unknown image mode
What it means
pil_to_array handles Pillow modes RGBA/RGBX/RGB/L directly and the I;16* family via raw byte swapping; every other mode must be convertible via pilImage.convert('RGBA'). When that conversion itself raises ValueError (exotic, corrupt, or unsupported pixel formats), matplotlib re-raises it as RuntimeError('Unknown image mode') during plt.imread.
Source
Thrown at lib/matplotlib/image.py:1793
- (M, N, 3) for RGB images.
- (M, N, 4) for RGBA images.
"""
if pilImage.mode in ['RGBA', 'RGBX', 'RGB', 'L']:
# return MxNx4 RGBA, MxNx3 RBA, or MxN luminance array
return np.asarray(pilImage)
elif pilImage.mode.startswith('I;16'):
# return MxN luminance array of uint16
raw = pilImage.tobytes('raw', pilImage.mode)
if pilImage.mode.endswith('B'):
x = np.frombuffer(raw, '>u2')
else:
x = np.frombuffer(raw, '<u2')
return x.reshape(pilImage.size[::-1]).astype('=u2')
else: # try to convert to an rgba image
try:
pilImage = pilImage.convert('RGBA')
except ValueError as err:
raise RuntimeError('Unknown image mode') from err
return np.asarray(pilImage) # return MxNx4 RGBA array
def _pil_png_to_float_array(pil_png):
"""Convert a PIL `PNGImageFile` to a 0-1 float array."""
# Unlike pil_to_array this converts to 0-1 float32s for backcompat with the
# old libpng-based loader.
# The supported rawmodes are from PIL.PngImagePlugin._MODES. When
# mode == "RGB(A)", the 16-bit raw data has already been coarsened to 8-bit
# by Pillow.
mode = pil_png.mode
rawmode = pil_png.png.im_rawmode
if rawmode == "1": # Grayscale.
return np.asarray(pil_png, np.float32)
if rawmode == "L;2": # Grayscale.
return np.divide(pil_png, 2**2 - 1, dtype=np.float32)
if rawmode == "L;4": # Grayscale.
return np.divide(pil_png, 2**4 - 1, dtype=np.float32)View on GitHub (pinned to b379c1b69e)
Solutions
- Pre-open and normalize with Pillow yourself: arr = np.asarray(PIL.Image.open(path).convert('RGB')) before handing data to matplotlib.
- Catch the RuntimeError and retry with an explicit convert(), logging the offending file's mode for triage.
- Verify file integrity (PIL.Image.open(...).verify()) and re-download corrupt transfers.
Example fix
# before
arr = plt.imread('scan.dat.png') # RuntimeError: Unknown image mode
# after
import numpy as np, PIL.Image
with PIL.Image.open('scan.dat.png') as im:
arr = np.asarray(im.convert('RGB')) Defensive patterns
Strategy: try-catch
Validate before calling
import PIL.Image
with PIL.Image.open(path) as im:
if im.mode not in {'RGBA', 'RGBX', 'RGB', 'L'} and not im.mode.startswith('I;16'):
im = im.convert('RGBA') # normalize before imread/matplotlib
arr = plt.imread(path) Try / catch
try:
arr = plt.imread(path)
except RuntimeError as err:
if 'Unknown image mode' not in str(err):
raise
import numpy as np, PIL.Image
with PIL.Image.open(path) as im:
arr = np.asarray(im.convert('RGB')) Prevention
- Pre-convert untrusted images with PIL Image.convert('RGB'|'RGBA').
- Verify() downloads before reading to catch truncated files.
- Log im.mode of failing files to detect Pillow-version regressions.
When it happens
Trigger: plt.imread on an image whose Pillow mode cannot convert to RGBA — e.g. some CMYK/palette variants with broken profiles, 1-bit or unusual bit-depth files depending on the Pillow version, or truncated/corrupt downloads (partial file saved from a failed transfer).
Common situations: Bulk-loading user-uploaded or scraped images where formats are uncontrolled; Pillow major-version upgrades changing supported modes; reading files whose extension lies about the actual format.
Related errors
- Please open the URL for reading and pass the result to Pillo
- Unknown PIL rawmode: {rawmode}
- The installed pillow version does not support avif. Full avi
- Matplotlib requires {modname}>={minver}; you have {module.__
- str(_cpe)
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/d710e17d2b238da5.
Report an issue: GitHub.