Bug Report: Gemini `Part.from_uri()` returns "The document has no pages" for valid PDF (both Gemini & Vertex AI APIs)

Bug Report: Gemini Part.from_uri() returns “The document has no pages” for valid PDF

Environment

Component Version
SDK google-genai 1.60.0
Python 3.13.11
Model gemini-2.5-pro

Issue

types.Part.from_uri(file_uri=sas_url, mime_type='application/pdf') returns error 400 INVALID_ARGUMENT: "The document has no pages." for a valid, accessible PDF.

This uses the signed URL feature announced in Increased file size limits and expanded inputs support in Gemini API (Jan 12, 2026):

We now support both files stored in public domains, as well as private storage (via signed URLs). We support pre-signed URLs for accessing data from AWS S3, Azure Blob Storage or other cloud providers.

Reproduction

from google import genai
from google.genai import types

# Fails with BOTH APIs:
client = genai.Client(api_key="...")  # Gemini Developer API
client = genai.Client(vertexai=True, project="...", location="global")  # Vertex AI

pdf_part = types.Part.from_uri(
    file_uri="<azure_blob_sas_url>",
    mime_type="application/pdf"
)

response = client.models.generate_content(
    model='gemini-2.5-pro',
    contents=[pdf_part, {'text': 'How many pages does this PDF have?'}],
)
# Error: 400 INVALID_ARGUMENT. "The document has no pages."

Evidence the PDF is valid

Check Result
HTTP HEAD on SAS URL 200 OK
Content-Type header application/pdf
Content-Length header 87997886 (88 MB)
Pages extracted by pdfium 359
OCR completed All 359 pages
PDF metadata extracted Yes (Author, Creator, dates)

PDF Details

  • Size: 88 MB (within 100 MB limit for signed URLs)
  • Pages: 359
  • Creator: Adobe Acrobat 25.1.21111
  • Created: Jan 23, 2026

What We Tried

  1. Gemini Developer API (AI Studio)

    client = genai.Client(api_key="...")
    

    Error: “The document has no pages.”

  2. Vertex AI API (Global endpoint)

    client = genai.Client(vertexai=True, project="...", location="global")
    

    Error: “The document has no pages.”

  3. Verified URL accessibility

    • HEAD request returns 200 OK with correct Content-Type: application/pdf
    • URL is a valid Azure Blob Storage SAS URL with 2-hour expiry
  4. Simple prompt test

    contents=[pdf_part, {'text': 'How many pages does this PDF have?'}]
    

    Same error with both APIs.

  5. Verified PDF integrity locally

    • Our preprocessing pipeline (using pdfium) successfully:
      • Extracted page count (359)
      • Extracted page dimensions for all pages
      • Ran OCR on all 359 pages
      • Extracted PDF metadata

Why Part.from_bytes() is not an option

The PDF is 88 MB, which exceeds the ~50 MB limit for inline PDF data. The signed URL feature was specifically designed for this use case per the Jan 12 announcement.

Expected Behavior

Per the documentation and blog announcement above, Gemini should fetch the PDF via the Azure Blob Storage signed URL and process its 359 pages.

Actual Behavior

Gemini returns “The document has no pages” despite the PDF being valid and accessible.

Workaround

Extracting OCR text separately and sending as text content works. Only the from_uri path fails.