huggingface/transformers · error · ValueError

The image to be converted to a PIL image contains values out

Error message

The image to be converted to a PIL image contains values outside the range [0, 1], got [{image.min()}, {image.max()}] which cannot be converted to uint8.

What it means

Companion guard in _rescale_for_pil_conversion: when the image holds non-integral values that are not all within [0, 1], PIL conversion is impossible. Float pixels are expected to be either full-range [0, 255] integers-in-float or normalized [0, 1]; anything else (e.g. [0, 2], negatives, standardized data) fails.

Source

Thrown at src/transformers/image_transforms.py:147

    Detects whether or not the image needs to be rescaled before being converted to a PIL image.

    The assumption is that if the image is of type `np.float` and all values are between 0 and 1, it needs to be
    rescaled.
    """
    if image.dtype == np.uint8:
        do_rescale = False
    elif np.allclose(image, image.astype(int)):
        if np.all(image >= 0) and np.all(image <= 255):
            do_rescale = False
        else:
            raise ValueError(
                "The image to be converted to a PIL image contains values outside the range [0, 255], "
                f"got [{image.min()}, {image.max()}] which cannot be converted to uint8."
            )
    elif np.all(image >= 0) and np.all(image <= 1):
        do_rescale = True
    else:
        raise ValueError(
            "The image to be converted to a PIL image contains values outside the range [0, 1], "
            f"got [{image.min()}, {image.max()}] which cannot be converted to uint8."
        )
    return do_rescale


def to_pil_image(
    image: Union[np.ndarray, "PIL.Image.Image", "torch.Tensor"],
    do_rescale: bool | None = None,
    image_mode: str | None = None,
    input_data_format: str | ChannelDimension | None = None,
) -> "PIL.Image.Image":
    """
    Converts `image` to a PIL Image. Optionally rescales it and puts the channel dimension back as the last axis if
    needed.

    Args:
        image (`PIL.Image.Image` or `numpy.ndarray` or `torch.Tensor`):

View on GitHub (pinned to a597f97485)

Solutions

  1. De-normalize before display: img = img * std + mean, then rescale to 0-255 if it was 0-1.
  2. If your floats are in [0, 1], ensure no stray value exceeds 1 (clip with np.clip(img, 0, 1)).
  3. Explicitly control conversion: to_pil_image((img * 255).astype(np.uint8), do_rescale=False).

Example fix

# before
pil = to_pil_image(normalized_img)  # values in [-2.4, 2.6] -> raises

# after
denorm = normalized_img * np.array(std) + np.array(mean)
pil = to_pil_image(np.clip(denorm, 0, 1), do_rescale=True)
Defensive patterns

Strategy: validation

Validate before calling

assert np.all(image >= 0) and np.all(image <= 1) or np.allclose(image, np.clip(image, 0, 255)), "image range not 0-1 nor integral 0-255; de-normalize or rescale first"

Prevention

When it happens

Trigger: to_pil_image on a normalized image ((img - mean)/std produces values like -2.1..2.1), float arrays with values 0-510, or images scaled to [0, 2]. Also triggered inside resize when a non-PIL image with bad range is passed.

Common situations: Visualizing images after Normalize, mixing rescale and normalize step order, or custom float pipelines that never establish a 0-1 or 0-255 convention.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/1ab0b04a61e1279a. Report an issue: GitHub.