Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

WeasyPrint image timeouts are usually URL-fetching problems, not PDF layout problems. The fetcher’s HTTP, HTTPS, and FTP timeout defaults to 10 seconds; set an explicit timeout, verify the final image URL from the rendering host, provide a correct base URL, and add a custom fetcher when assets require cookies or authorization. Then choose whether missing images should produce warnings or fail the render.

What the timeout actually controls

When WeasyPrint encounters an external <img>, CSS background, or stylesheet, it retrieves that resource through a URL fetcher. The fetcher performs DNS lookup, TLS negotiation, redirects, authentication and data transfer before the layout engine can use the bytes. A browser loading the same page successfully does not prove that the machine running WeasyPrint can reach the resource or has the same credentials.

The documented URLFetcher default is a 10-second timeout for HTTP, HTTPS and FTP resources. A timeout value applies to network protocols; it does not alter how file:// URLs are handled. Increasing the value gives a slow but reachable server more time. It cannot fix a wrong hostname, blocked egress, a failed certificate, an unauthorized response, or an image URL that never resolves.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Diagnose the failing image before changing settings

  1. Log the final URL

    Log the rendered src after template substitution, not only the template value. Look for an empty variable, an accidental relative path, an expired signed URL, spaces that were not encoded, or a redirect to a different host.

  2. Test from the rendering machine

    Use the exact URL from the same container, worker or server that runs WeasyPrint. Check DNS resolution, TLS certificate validation, redirect targets, HTTP status and elapsed time. A request that succeeds on a developer laptop may fail in a private subnet, container, serverless function or job queue.

  3. Check the response itself

    Confirm that the endpoint returns an image rather than an HTML login page, a bot challenge, a 403/404 response, or an oversized file. Inspect Content-Type and response length. A fast 401 is an authentication problem, not a timeout problem.

  4. Separate one bad asset from a slow page

    Temporarily remove images one at a time or render a minimal document containing the suspected URL. If one host causes every job to stall, investigate that origin. If only one very large image is slow, optimize or resize that asset.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set an explicit timeout in Python

Pass a fetcher to HTML and keep the value in application configuration so it is visible and adjustable. This example gives network resources 20 seconds:

from weasyprint import HTML
from weasyprint.urls import URLFetcher

fetcher = URLFetcher(timeout=20)
HTML(
    string=html,
    base_url="https://app.example/",
    url_fetcher=fetcher,
).write_pdf("out.pdf")

Choose the value from observed response times and your job’s deadline rather than setting it arbitrarily high. A 20-second timeout is useful for a service that occasionally responds slowly; it does not make an unavailable service reliable. Set a process-level deadline as well, because a page can contain several resources and each request may consume time.

Fix relative image paths with base_url

Markup such as <img src="images/logo.png"> has no useful meaning when HTML is supplied as a string unless WeasyPrint receives a base URL. Provide the directory or origin against which relative URLs should be resolved:

from weasyprint import HTML

HTML(
    string='<img src="images/logo.png">',
    base_url="https://app.example/",
).write_pdf("out.pdf")

For local files, use a deliberate local base directory and verify that the resulting path is the one you intended. On the command line, the equivalent control is --base-url. A missing or incorrect base URL often looks like an image timeout because the PDF is generated with a missing image while a browser, which already has a page origin, displays it correctly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Increase the timeout from the command line

The CLI exposes --timeout <timeout> for HTTP requests. Combine it with a base URL when the document contains relative paths:

weasyprint --timeout 20 --base-url https://app.example/ input.html out.pdf

Use the CLI’s HTTP-error option while diagnosing so an HTTP failure is visible instead of silently producing a PDF with a missing asset. Keep the strict setting in CI or quality-sensitive pipelines; for production documents where a noncritical decorative image may be omitted, you may prefer a warning-and-continue policy.

Make fetch failures visible

WeasyPrint generally catches resource-fetch errors and emits warnings, so a PDF can exist even though one or more images were not loaded. During investigation, enable fail_on_errors where your installed API supports it, or use the CLI’s --fail-on-http-errors. A hard failure is appropriate when an invoice, legal exhibit or report must contain every image. A tolerant policy can be appropriate for an optional avatar or decorative background.

Record the URL, exception, HTTP status and document identifier in your logs. Avoid logging authorization headers, session cookies or signed URLs in full.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Authenticate protected images with a custom fetcher

The default fetcher handles normal file and HTTP URLs but does not provide your application’s session cookies, bearer token policy or special request headers. Wrap or subclass the fetcher, add credentials only for the hosts that need them, and delegate all other URLs to the default implementation. Return the response shape expected by your installed WeasyPrint version, including a byte stream and an appropriate MIME type.

from io import BytesIO
from weasyprint import HTML
from weasyprint.urls import URLFetcher

class AuthFetcher(URLFetcher):
    def __init__(self, token, **kwargs):
        super().__init__(**kwargs)
        self.token = token

    def fetch(self, url):
        if url.startswith("https://private.example/"):
            import requests
            response = requests.get(
                url,
                headers={"Authorization": f"Bearer {self.token}"},
                timeout=self.timeout,
            )
            response.raise_for_status()
            return {
                "string": BytesIO(response.content),
                "mime_type": response.headers.get("Content-Type", "application/octet-stream"),
            }
        return super().fetch(url)

fetcher = AuthFetcher(token="TOKEN", timeout=20)
HTML(string=html, base_url="https://app.example/", url_fetcher=fetcher).write_pdf("out.pdf")

Adapt the return value to the exact WeasyPrint release you deploy and test redirects carefully. Restrict credentials to an allow-listed origin; never forward a bearer token to arbitrary URLs from untrusted HTML. For cookie-based authentication, create a request with the required cookie jar and return the downloaded bytes, or use a signed, short-lived asset URL.

Match the fix to the failure cause

Symptom Likely cause Corrective action Scope
Relative path cannot be found No meaningful document origin Set base_url or CLI --base-url URL resolution
Request exceeds 10 seconds Slow but reachable origin Set URLFetcher(timeout=...) or CLI --timeout Network wait
401 or 403 response Missing token, cookie or signed URL Use a host-restricted custom fetcher or authenticated asset endpoint Credentials
Browser works, worker fails DNS, firewall, proxy or TLS differences Test from the rendering host and fix egress or certificates Deployment
PDF succeeds with a blank image Fetch warning was tolerated Enable strict HTTP-error handling while diagnosing Failure policy
Large images delay or exhaust jobs Excessive transfer or decode cost Resize and compress images; cap embedded resolution with dpi Payload and memory

Reduce latency and resource use without hiding outages

Serve stable assets locally when appropriate

If an image is versioned and public to the rendering service, serving it from local storage or the same low-latency origin removes a remote dependency. Do this only when the file-access policy is safe and the path is controlled.

Optimize the source image

Downscale images to the size they will occupy on the page, choose a suitable format, and remove unnecessary metadata. This reduces transfer, decoding time and PDF memory. The dpi option can cap effective embedded resolution; it does not repair a server that cannot be reached.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Cache repeated resources

Use WeasyPrint’s image-cache or disk cache-folder controls for repeated jobs where the same assets are fetched again. Set an invalidation strategy when files change. Caching addresses repeated work, not the first failed request or an unreachable host.

Control concurrency

Several simultaneous documents can multiply outbound requests and memory use. Bound worker concurrency, apply per-job time and memory limits, and measure total render duration as well as individual fetch time.

Security and deployment safeguards

HTML and CSS that come from users can turn network and file URL support into a server-side request or local-file disclosure risk. Before increasing timeouts:

  • Allow only required URL schemes and hosts.
  • Filter or reject file:// access unless the document is fully trusted.
  • Sanitize external URLs and prevent redirects to internal metadata or control-plane addresses.
  • Keep authorization headers and cookies off untrusted origins.
  • Enforce process-level time and memory limits.
  • Use separate rendering workers or containers when documents are untrusted.

A larger timeout can amplify resource exhaustion: an attacker can provide many slow URLs, each consuming a worker. Set a finite per-request timeout and an overall render deadline.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

A repeatable troubleshooting runbook

  1. Capture the expanded image URL and document identifier in logs.
  2. Request that URL from the exact rendering host; record DNS, TLS, redirects, status and duration.
  3. Render a minimal HTML file containing only the image.
  4. Set base_url if the path is relative.
  5. Set an explicit fetcher timeout and retry once only if your service’s retry policy permits it.
  6. For 401/403 responses, implement a restricted custom fetcher or issue a signed URL.
  7. Enable strict HTTP-error handling and decide whether this document class should fail on missing images.
  8. Optimize oversized assets and configure caching for repeated jobs.
  9. Restore normal tolerance only after logs and output checks prove the behavior is acceptable.

Or skip the browser setup

If your goal is a clean screenshot or PDF of a web page rather than a WeasyPrint document, ScreenshotNeo makes one GET request and returns PNG, JPEG, WebP or PDF. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

See the ScreenshotNeo API documentation for all options. A direct call is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

There are also 63 options, including full-page lazy-image loading, CSS-selector element capture, dark mode, device presets, retina scale, PDF paper and margin controls, custom CSS and JavaScript, clicks, selector waits, network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs are accepted to ease migration.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to try it.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python and Node.js alternatives for ScreenshotNeo

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

FAQ

Does increasing the timeout change local-file access?

No. The timeout governs network protocols; it does not change file:// behavior or permissions.

Why does WeasyPrint create a PDF even when an image is missing?

Fetch errors are commonly reported as warnings while rendering continues. Use strict HTTP-error handling during diagnosis or for documents that require every asset.

Should I retry every timeout?

Only when the failure is plausibly transient and your overall job deadline allows it. Retrying a blocked host or invalid URL adds delay without improving the result.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.