microsoft/markitdown · error · ValueError
Malformed data URI, missing ',' separator
Error message
Malformed data URI, missing ',' separator
What it means
RFC 2397 data URIs are '<mediatype>[;base64],<data>'; parse_data_uri() splits on the first comma and treats an empty separator (no comma at all) as malformed, raising this ValueError. The check uses uri.partition(',') so a URI that ends at the header ('data:text/plain') with no ',' and no payload triggers it.
Source
Thrown at packages/markitdown/src/markitdown/_uri_utils.py:25
def file_uri_to_path(file_uri: str) -> Tuple[str | None, str]:
"""Convert a file URI to a local file path"""
parsed = urlparse(file_uri)
if parsed.scheme != "file":
raise ValueError(f"Not a file URL: {file_uri}")
netloc = parsed.netloc if parsed.netloc else None
path = os.path.abspath(url2pathname(parsed.path))
return netloc, path
def parse_data_uri(uri: str) -> Tuple[str | None, Dict[str, str], bytes]:
if not uri.startswith("data:"):
raise ValueError("Not a data URI")
header, _, data = uri.partition(",")
if not _:
raise ValueError("Malformed data URI, missing ',' separator")
meta = header[5:] # Strip 'data:'
parts = meta.split(";")
is_base64 = False
# Ends with base64?
if parts[-1] == "base64":
parts.pop()
is_base64 = True
mime_type = None # Normally this would default to text/plain but we won't assume
if len(parts) and len(parts[0]) > 0:
# First part is the mime type
mime_type = parts.pop(0)
attributes: Dict[str, str] = {}
for part in parts:
# Handle key=value pairs in the middleView on GitHub (pinned to fd239d5d2b)
Solutions
- Fix the generator to always emit '<mime>[;base64],<data>' with the comma
- Validate user-supplied data URIs with a regex before conversion
- If the payload is empty on purpose, send 'data:text/plain,'
Example fix
# before
md.convert_uri("data:application/pdf") # ValueError: missing ','
# after
md.convert_uri("data:application/pdf;base64,JVBERi0...") Defensive patterns
Strategy: validation
Validate before calling
import re
DATA_URI_RE = re.compile(r"^data:[^,]*;base64,[A-Za-z0-9+/=]+$|^data:[^,]*,.+$")
def is_wellformed_data_uri(uri: str) -> bool:
return uri.startswith("data:") and "," in uri Try / catch
try:
result = md.convert_uri(data_uri)
except ValueError as e:
if "missing ','" in str(e):
raise ValueError("data URI truncated: header present but no payload") from e
raise Prevention
- Validate data URIs with a regex before storing or converting them
- When concatenating base64 payloads, always template as 'data:<mime>;base64,<payload>'
- Guard against silent truncation of very long URIs in logs, clipboards, and config files
When it happens
Trigger: md.convert_uri('data:text/plain') or 'data:application/pdf' — header present but the comma and data section missing; also truncated copies of data URIs.
Common situations: Template strings or string concatenation that drops the payload, clipboard truncation of very long base64 URIs, or building data URIs with a missing ',' separator during generation.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Not a data URI
- Unsupported file URI: {uri}. Netloc must be empty or localho
- Unsupported URI scheme: {uri.split(':')[0]}. Supported schem
- Not a file URL: {file_uri}
- No channel found in RSS feed
AI-assisted analysis of microsoft/markitdown@fd239d5d2b (2026-08-14).
Data as JSON: /api/errors/066bad2bfab35227.
Report an issue: GitHub.