microsoft/markitdown · error · ValueError
Unsupported URI scheme: {uri.split(':')[0]}. Supported schem
Error message
Unsupported URI scheme: {uri.split(':')[0]}. Supported schemes are: file:, data:, http:, https: What it means
convert_uri() only handles four schemes: file:, data:, http:, https:. Any other scheme falls through to a ValueError that echoes the scheme prefix (everything before the first colon). This is a fast-fail guard so unsupported protocols (ftp:, s3:, mailto:, blob:) never reach network or filesystem code.
Source
Thrown at packages/markitdown/src/markitdown/_markitdown.py:485
io.BytesIO(data),
stream_info=base_guess,
file_extension=file_extension,
url=mock_url,
**kwargs,
)
# HTTP/HTTPS URIs
elif uri.startswith("http:") or uri.startswith("https:"):
response = self._requests_session.get(uri, stream=True)
response.raise_for_status()
return self.convert_response(
response,
stream_info=stream_info,
file_extension=file_extension,
url=mock_url,
**kwargs,
)
else:
raise ValueError(
f"Unsupported URI scheme: {uri.split(':')[0]}. Supported schemes are: file:, data:, http:, https:"
)
def convert_response(
self,
response: requests.Response,
*,
stream_info: Optional[StreamInfo] = None,
file_extension: Optional[str] = None, # Deprecated -- use stream_info
url: Optional[str] = None, # Deprecated -- use stream_info
**kwargs: Any,
) -> DocumentConverterResult:
# If there is a content-type header, get the mimetype and charset (if present)
mimetype: Optional[str] = None
charset: Optional[str] = None
if "content-type" in response.headers:
parts = response.headers["content-type"].split(";")View on GitHub (pinned to fd239d5d2b)
Solutions
- Download non-HTTP resources first, then pass the local path or a BytesIO stream
- For Windows paths, pass them as plain paths to convert(), not to convert_uri()
- Prefix valid web URIs with http:// or https:// explicitly
Example fix
# before
md.convert_uri("s3://bucket/doc.pdf") # ValueError: Unsupported URI scheme: s3
# after
import boto3, io
body = boto3.client("s3").get_object(Bucket="bucket", Key="doc.pdf")["Body"].read()
md.convert(io.BytesIO(body), stream_info=StreamInfo(extension=".pdf", mimetype="application/pdf")) Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_SCHEMES = ("file:", "data:", "http:", "https:")
def is_supported_uri(uri: str) -> bool:
return uri.startswith(SUPPORTED_SCHEMES) Try / catch
try:
result = md.convert_uri(uri)
except ValueError as e:
if "Unsupported URI scheme" in str(e):
# fetch via the right client, then convert the bytes
raise
raise Prevention
- Whitelist schemes at input validation time: file, data, http, https
- Convert cloud URIs (s3://, gs://) to local paths or streams before calling markitdown
- Never pass Windows drive-letter paths to convert_uri(); use convert() instead
When it happens
Trigger: md.convert_uri('ftp://host/file.pdf'), md.convert_uri('s3://bucket/key.docx'), md.convert_uri('mailto:a@b.com'), or a relative string without any scheme (split(':')[0] then yields the whole first token).
Common situations: Passing cloud-storage URIs (s3://, gs://, abfs://) or Windows drive paths ('C:\file.docx', where 'C' is reported as the scheme) instead of local paths or HTTP URLs.
Related errors
- Unsupported file URI: {uri}. Netloc must be empty or localho
- Not a file URL: {file_uri}
- Not a data URI
- Malformed data URI, missing ',' separator
- Error converting .ipynb file: {str(e)}
AI-assisted analysis of microsoft/markitdown@fd239d5d2b (2026-08-14).
Data as JSON: /api/errors/4946f9b8dec6c5be.
Report an issue: GitHub.