BerriAI/litellm · error · ValueError

Bedrock Converse only supports base64-encoded document sourc

Error message

Bedrock Converse only supports base64-encoded document sources, got '{source_type}'. Please convert the document to base64 before sending to Bedrock.

What it means

Bedrock Converse's document ingestion (_process_document_message) only accepts Anthropic-style sources with source.type == 'base64'. A document block whose source type is 'url', 'file', or anything else raises this ValueError telling you to base64-encode the document.

Source

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

        if file_data is None and file_id is None:
            raise litellm.BadRequestError(
                message=f"file_data and file_id cannot both be None. Got={message}",
                model="",
                llm_provider="bedrock",
            )
        return await BedrockImageProcessor.process_image_async(image_url=cast(str, file_id or file_data), format=format)

    @staticmethod
    def _process_document_message(element: dict) -> BedrockContentBlock:
        """Convert a document content block to a Bedrock DocumentBlock.

        Handles the Anthropic-style document format:
        {"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": "..."}}
        """
        source: Final = element["source"]
        source_type: Final = source.get("type")
        if source_type != "base64":
            raise ValueError(
                f"Bedrock Converse only supports base64-encoded document sources, got '{source_type}'. "
                "Please convert the document to base64 before sending to Bedrock."
            )
        media_type: Final[str] = source["media_type"]
        data: Final[str] = source["data"]
        doc_format = BedrockImageProcessor._validate_format(mime_type=media_type, image_format=media_type.split("/")[1])

        # Deterministic name using the same hashing pattern as _create_bedrock_block
        HASH_SAMPLE_BYTES: Final = 64 * 1024
        normalized: Final = "".join(data.split()).encode("utf-8")
        sample: Final = normalized[:HASH_SAMPLE_BYTES]
        hasher: Final = hashlib.sha256()
        hasher.update(sample)
        hasher.update(str(len(normalized)).encode("utf-8"))
        content_hash: Final = hasher.hexdigest()[:16]
        document_name: Final = f"Document_{content_hash}_{doc_format}"

        return BedrockContentBlock(

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Fetch the document (PDF/TXT/MD/DOCX) and inline it: source = {"type": "base64", "media_type": "application/pdf", "data": <b64>}.
  2. For Anthropic-style URLs, download and encode before the call when targeting Bedrock.
  3. Check media_type is a supported Bedrock format (pdf, txt, md, docx, xlsx, csv).

Example fix

# before
{"type": "document", "source": {"type": "url", "url": "https://x/report.pdf"}}
# after
import base64, requests
data = base64.b64encode(requests.get("https://x/report.pdf").content).decode()
{"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": data}}
Defensive patterns

Strategy: validation

Validate before calling

def to_bedrock_document(url: str, media_type: str = "application/pdf") -> dict:
    data = base64.b64encode(requests.get(url, timeout=60).content).decode()
    return {"type": "document", "source": {"type": "base64", "media_type": media_type, "data": data}}

Type guard

def is_bedrock_doc_source(source) -> bool:
    return isinstance(source, dict) and source.get("type") == "base64" and "data" in source and "media_type" in source

Try / catch

try:
    resp = litellm.completion(model="bedrock/...", messages=msgs)
except ValueError as e:
    if "only supports base64-encoded document sources" in str(e):
        msgs = rebuild_docs_as_base64(msgs)
        resp = litellm.completion(model="bedrock/...", messages=msgs)

Prevention

When it happens

Trigger: Sending {"type": "document", "source": {"type": "url", "url": ...}} (valid for some Anthropic endpoints) to a bedrock/... model; or a source dict missing/typoing the 'type' key (source_type None).

Common situations: Sharing the same PDF message payload between Anthropic direct and Bedrock routes; copy-pasting Anthropic docs examples; source dicts built dynamically where 'type' is omitted.

Related errors


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