BerriAI/litellm · error · ValueError
Unable to determine content type from URL: {url}. Response c
Error message
Unable to determine content type from URL: {url}. Response content-type: {current_content_type} What it means
When litellm downloads an image from a URL (for vision inputs), it tries several strategies to determine the content type: the HTTP response's Content-Type header, magic-byte sniffing of the downloaded bytes (png/jpeg/gif/webp/heic detection), and filename hints. If all fallbacks fail — the header is generic/missing and the bytes don't match a known image signature — it raises ValueError with the URL and the header value it saw.
Source
Thrown at litellm/litellm_core_utils/prompt_templates/common_utils.py:1233
if inferred_type:
return inferred_type
# Try to detect from binary content signature (magic bytes)
if content:
detected_type: Final = get_image_type(content[:100])
if detected_type:
type_to_mime: Final = {
"png": "image/png",
"jpeg": "image/jpeg",
"gif": "image/gif",
"webp": "image/webp",
"heic": "image/heic",
}
if detected_type in type_to_mime:
return type_to_mime[detected_type]
# If all fallbacks failed, raise error
raise ValueError(f"Unable to determine content type from URL: {url}. Response content-type: {current_content_type}")
def get_tool_call_names(tools: list[ChatCompletionToolParam]) -> list[str]:
"""
Get tool call names from tools
"""
tool_call_names: Final[list[str]] = []
for tool in tools:
if tool.get("type") == "function":
tool_call_name = tool.get("function", {}).get("name")
if tool_call_name:
tool_call_names.append(tool_call_name)
return tool_call_names
def is_function_call(optional_params: dict) -> bool:
"""
Checks if the optional params contain the function callView on GitHub (pinned to 6c2dcb801b)
Solutions
- Verify the URL actually returns image bytes: curl -I <url> and check Content-Type; open it in a browser.
- Convert the image to PNG/JPEG and re-host it where the server sets a correct Content-Type.
- For SVGs, rasterize to PNG first — most vision models don't accept SVG anyway.
- Refresh expired signed URLs; ensure auth cookies/headers aren't required for the fetch.
- If the format is supported but the server header is wrong, embed the image as base64 data URL with an explicit mime type.
Example fix
// before
{'type':'image_url','image_url':{'url':'https://cdn.example.com/chart.svg'}}
# after (rasterize + embed base64)
import base64
png_b64 = base64.b64encode(open('chart.png','rb').read()).decode()
{'type':'image_url','image_url':{'url':f'data:image/png;base64,{png_b64}'}} Defensive patterns
Strategy: validation
Validate before calling
import urllib.request
def url_serves_image(url: str) -> bool:
req = urllib.request.Request(url, method='GET', headers={'Range': 'bytes=0-15'})
with urllib.request.urlopen(req, timeout=10) as r:
ctype = r.headers.get('Content-Type', '')
magic = r.read(16)
if ctype.startswith('image/') and 'svg' not in ctype:
return True
return magic[:8] in (b'\x89PNG\r\n\x1a\n', b'\xff\xd8\xff') or magic[:4] == b'RIFF' Try / catch
try:
resp = litellm.completion(model=m, messages=[{'role':'user','content':[{'type':'image_url','image_url':{'url':u}},'describe this']}])
except ValueError as e:
if 'Unable to determine content type' in str(e):
u = to_base64_data_url(u) # download, convert to PNG, embed as data URL
resp = litellm.completion(model=m, messages=[{'role':'user','content':[{'type':'image_url','image_url':{'url':u}},'describe this']}])
else:
raise Prevention
- Pre-validate image URLs with a HEAD request before sending them to the model.
- Rasterize SVGs and exotic formats to PNG before upload.
- Refresh signed URLs at request time; don't cache them beyond their expiry.
When it happens
Trigger: Passing image_url pointing to non-image content (HTML error page, SVG without a sniffable signature, login-redirect page); servers returning 'application/octet-stream' or 'text/html' with unrecognized bytes; exotic image formats not in the png/jpeg/gif/webp/heic sniff table.
Common situations: Expired/signed S3 or CDN URLs that redirect to an HTML login page; SVGs (content-type image/svg+xml but no magic bytes match in the table); WebP variants or AVIF images unsupported by the sniffer; misconfigured static servers omitting Content-Type.
Related errors
- URL does not point to a valid image (content-type: {content_
- ollama image conversion failed please run `pip install Pillo
- Invalid image URL: {content_image_url}
- Unable to get Image Response. Please pass a valid llm_provid
- Image url not in expected format. Example Expected input - "
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/f204737776107278.
Report an issue: GitHub.