BerriAI/litellm · error · Exception

Image url not in expected format. Example Expected input - "

Error message

Image url not in expected format. Example Expected input - "image_url": "data:image/jpeg;base64,{base64_image}". Supported formats - ['image/jpeg', 'image/png', 'image/gif', 'image/webp']. Error: {e}

What it means

Raised while building a GenericImageParsingChunk from an image_url: the extraction of media_type/base64 data failed for any reason other than an ImageFetchError (which is re-raised untouched). Common causes are data URIs whose media type is not image/jpeg, png, gif, or webp, or a malformed base64 payload after the ';base64,' marker.

Source

Thrown at litellm/litellm_core_utils/prompt_templates/factory.py:858

        if openai_image_url.startswith("http"):
            openai_image_url = convert_url_to_base64(url=openai_image_url)
        # Extract the media type and base64 data
        media_type, base64_data = openai_image_url.split("data:")[1].split(";base64,")

        if format:
            media_type = format
        else:
            media_type = media_type.replace("\\/", "/")

        return GenericImageParsingChunk(
            type="base64",
            media_type=media_type,
            data=base64_data,
        )
    except litellm.ImageFetchError:
        raise
    except Exception as e:
        raise Exception(
            f"""Image url not in expected format. Example Expected input - "image_url": "data:image/jpeg;base64,{{base64_image}}". Supported formats - ['image/jpeg', 'image/png', 'image/gif', 'image/webp']. Error: {e}"""
        )


def create_anthropic_image_param(
    image_url_input: str | dict,
    format: str | None = None,
    is_bedrock_invoke: bool = False,
) -> AnthropicMessagesImageParam:
    """
    Create an AnthropicMessagesImageParam from an image URL input.

    Supports both URL references (for HTTP/HTTPS URLs) and base64 encoding.
    """
    # Extract URL and format from input
    if isinstance(image_url_input, str):
        image_url = image_url_input
    else:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Convert the image to a supported type (jpeg/png/gif/webp) before sending, e.g. with Pillow: img.convert('RGB').save(buf, 'JPEG')
  2. Fix the data URI so it reads data:image/<jpeg|png|gif|webp>;base64,<clean base64>
  3. For SVG, rasterize to PNG first
  4. Strip whitespace/newlines from base64 payloads introduced by copy-paste or line wrapping

Example fix

# before
content = [{"type": "image_url", "image_url": {"url": "data:image/heic;base64,<b64>"}}]

# after
from PIL import Image
import io, base64
img = Image.open("photo.heic").convert("RGB")
buf = io.BytesIO(); img.save(buf, format="JPEG")
b64 = base64.b64encode(buf.getvalue()).decode()
content = [{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64}"}}]
Defensive patterns

Strategy: validation

Validate before calling

import re

SUPPORTED = {"jpeg", "jpg", "png", "gif", "webp"}
_DATA = re.compile(r"^data:image/([a-z0-9.+-]+);base64,")

def check_image_block(block: dict) -> None:
    url = block.get("image_url", {}).get("url", "")
    m = _DATA.match(url)
    if m and m.group(1).lower() not in SUPPORTED:
        raise ValueError(f"convert {m.group(1)} to jpeg/png/gif/webp before sending")

Type guard

import re
from typing import Any

_OK = {"jpeg", "jpg", "png", "gif", "webp"}
_RE = re.compile(r"^data:image/([a-z0-9.+-]+);base64,[A-Za-z0-9+/=]+$")

def is_supported_data_uri(v: Any) -> bool:
    if not isinstance(v, str):
        return False
    m = _RE.match(v)
    return bool(m and m.group(1).lower() in _OK)

Try / catch

try:
    litellm.completion(model=model, messages=messages)
except Exception as e:
    if "Image url not in expected format" in str(e) and "Supported formats" in str(e):
        messages = [convert_block_to_jpeg(m) for m in messages]  # Pillow re-encode
        litellm.completion(model=model, messages=messages)
    else:
        raise

Prevention

When it happens

Trigger: Vision input with media types like image/tiff, image/bmp, image/heic, image/svg+xml, or an empty/corrupt base64 segment; passing a dict where url/format keys are unexpected; hitting this on Anthropic/Bedrock image conversion paths that use the generic chunk builder.

Common situations: iPhone HEIC photos or BMP/TIFF screenshots fed directly to the API; SVG logos; WebP variants labelled 'image/jp2'; base64 strings with data-URI whitespace or truncated padding.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/f24da5f45988998d. Report an issue: GitHub.