{"record":{"id":"956818a06cd28499","repo":"crewAIInc/crewAI","slug":"failed-to-download-pdf-from-url-e-s","errorCode":null,"errorMessage":"Failed to download PDF from {url}: {e!s}","messagePattern":"Failed to download PDF from (.+?): (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/pdf_loader.py","lineNumber":67,"sourceCode":"        \"\"\"\n        headers = kwargs.get(\n            \"headers\",\n            {\n                \"Accept\": \"application/pdf\",\n                \"User-Agent\": \"Mozilla/5.0 (compatible; crewai-tools PDFLoader)\",\n            },\n        )\n\n        try:\n            body, _content_type, _final_url = safe_get_bounded(\n                url,\n                max_bytes=kwargs.get(\"max_bytes\", DEFAULT_MAX_PDF_BYTES),\n                headers=headers,\n                timeout=30,\n            )\n            return body\n        except Exception as e:\n            raise ValueError(f\"Failed to download PDF from {url}: {e!s}\") from e\n\n    def load(self, source: SourceContent, **kwargs: Any) -> LoaderResult:  # type: ignore[override]\n        \"\"\"Load and extract text from a PDF file or URL.\n\n        Args:\n            source: The source content containing the PDF file path or URL.\n\n        Returns:\n            LoaderResult with extracted text content.\n\n        Raises:\n            FileNotFoundError: If the PDF file doesn't exist.\n            ImportError: If required PDF libraries aren't installed.\n            ValueError: If the PDF cannot be read or downloaded.\n        \"\"\"\n        try:\n            import pymupdf  # type: ignore[import-untyped]\n        except ImportError as e:","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/pdf_loader.py#L49-L85","documentation":"Raised by PDFLoader._fetch_from_url() when anything fails while downloading a remote PDF: the bounded safe_get_bounded request (network error, HTTP error status after raise, exceeded max_bytes cap), or exceptions raised while returning the body. The broad except wraps it into ValueError with the URL and stringified cause.","triggerScenarios":"PDFLoader().load(SourceContent('https://example.com/paper.pdf')) where the URL 404s, the host is unreachable/TLS fails, the download exceeds max_bytes (default DEFAULT_MAX_PDF_BYTES) and is aborted, or the request times out at 30s.","commonSituations":"Broken/expired links to PDFs; sites requiring cookies or blocking non-browser agents; very large PDFs exceeding the byte cap; flaky mobile/corporate networks; PDF URLs that actually return HTML (though that usually fails later at parse time).","solutions":["Verify the link with curl -I — confirm 200 and application/pdf; fix or re-generate the URL.","For large PDFs, raise the cap: PDFLoader().load(src, max_bytes=50_000_000).","Retry transient failures once; cache downloaded PDFs locally and pass the file path on subsequent runs.","If the server blocks the default user-agent, download with your own session/headers and pass the local file."],"exampleFix":"# before\nresult = PDFLoader().load(SourceContent('https://example.com/big-report.pdf'))  # > max_bytes\n\n# after\nresult = PDFLoader().load(\n    SourceContent('https://example.com/big-report.pdf'),\n    max_bytes=100 * 1024 * 1024,\n)","handlingStrategy":"retry","validationCode":"import requests\\n\\ndef pdf_url_ok(url: str) -> bool:\\n    try:\\n        r = requests.head(url, timeout=10, allow_redirects=True)\\n        return r.ok and 'pdf' in r.headers.get('Content-Type', '')\\n    except requests.RequestException:\\n        return False","typeGuard":null,"tryCatchPattern":"try:\\n    result = PDFLoader().load(source)\\nexcept ValueError as e:\\n    if 'Failed to download PDF' in str(e):\\n        result = cached_or_retry_later(source.source)\\n    else:\\n        raise","preventionTips":["HEAD-check PDF links and their size before downloading.","Pass max_bytes sized to your real documents.","Cache downloads locally; re-run from the file path, not the URL."],"tags":["pdf","network","http","loader"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}