Most missing-image PDF failures have one of three causes: the renderer cannot resolve the image URL, the conversion process cannot fetch it, or rendering starts before JavaScript has finished inserting the image. Start by identifying the exact src value and the conversion input type (HTML string, local file, or remote URL). Then test that resolved resource from the same machine, container, account, and network used by the .NET process.
1. Identify what the renderer is actually loading
The same markup can work in a browser and fail in a PDF job because a browser supplies an origin, session, proxy, and user profile that your server-side renderer may not have. For every broken image, record its literal src, the absolute URL or file path produced by resolution, and the renderer’s input mode.
HTML string
An HTML fragment has no containing directory or web origin. A value such as images/logo.png cannot be resolved until you provide a base. SelectPdf states: “When you convert a string to pdf and have references to external resources, the converter needs to know the location of the html.” Its ConvertHtmlString overload accepts a baseUrl; that base combined with the relative path forms the resource URL. IronPDF likewise documents a base-path argument for local assets rendered from an HTML string.
using SelectPdf;
var html = "<html><body><img src="images/logo.png" /></body></html>";
var converter = new HtmlToPdf();
converter.Options.JavaScriptEnabled = true;
PdfDocument pdf = converter.ConvertHtmlString(
html,
"https://www.example.com/invoices/");
pdf.Save("invoice.pdf");
pdf.Close();
Use an HTTP origin when the assets are served by your application. Use a correctly formatted file URI or the renderer’s documented filesystem base when assets are local. Do not assume that /assets/logo.png means the root of your project; in a browser it means the root of the current origin, while in a file-based document it may resolve to the operating-system root.
Recommended Free Tools
#1 Best Overall
- INNOVATIVE CARTRIDGE-FREE PRINTING — No more dealing with lots of tiny ink cartridges; With this wireless document and photo printer each ink bottle set is equivalent to about 90 individual cartridges²
- LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; When you choose this combination printer, scanner and copier you can print up to 4,500 pages black/7,500 color³
- COLOR PRINTING — Up to 2 years of ink in the box4 (and with every replacement ink set) for fewer out-of-ink frustrations
- ZERO CARTRIDGE WASTE — By using an Epson EcoTank printer you can help reduce the amount of cartridge waste ending up in landfills
- HOME PRINTER DESIGNED FOR RELIABILITY — The Epson EcoTank ET-2800 All-in-One Supertank Color Printer creates vivid, detailed prints and documents thanks to Micro Piezo Heat-Free Technology; Fire off 10 ISO pages per minute1 to easily finish large jobs
Local HTML file
Confirm that each asset exists relative to the HTML file and that the conversion process identity can read it. IronPDF’s RenderHtmlFileAsPdf resolves relative CSS, images, and scripts from the file’s own folder, as if the document were opened with file://. A Windows account that can open the file interactively is not proof that a Windows service, IIS application pool, or container user can read it.
using IronPdf;
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlFileAsPdf(
Path.GetFullPath("templates/invoice.html"));
pdf.SaveAs("invoice.pdf");
Remote page
Open the exact image URL from the conversion host, not from your workstation. Check DNS, proxy rules, TLS certificates, redirects, authentication, cookies, response status, and whether the response body is actually image bytes rather than an HTML login or error page. SelectPdf’s troubleshooting guidance specifically calls out unresolved URLs, server reachability, and proxy configuration when navigation times out.
2. Inspect the markup and response before changing PDF settings
- Print the literal source. Log every
img[src]and CSS background URL. Look for whitespace, URL encoding mistakes, case differences (important on Linux), expired signed URLs, and accidental relative paths. - Resolve it independently. For an HTML string, combine the supplied base and relative path using the same URI rules as the renderer. For a local file, test the normalized filesystem path.
- Check the response. Follow redirects and verify a successful status, an image-compatible
Content-Type, and nonzero content length. A 200 response containing a login page still produces a missing image. - Check CSS images separately.
background-image:url(...)follows the stylesheet’s base URL, which may differ from the HTML document’s base.
If you control the markup, an explicit <base href="https://host/"> can establish a document base, but do not add one blindly: it changes the meaning of every relative link, script, stylesheet, and image. Passing the renderer’s documented base argument is usually easier to audit.
3. Make asynchronous images finish loading
Single-page applications often insert an <img> after navigation, lazy-load it on intersection, or fetch a signed URL in JavaScript. If PDF generation begins immediately after the initial response, the element can exist without its pixels. Iron Software says this issue is usually caused by assets not loading in time and recommends increasing WaitFor.RenderDelay, for example to 3,000 milliseconds or longer when needed.
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.RenderDelay(3000);
var pdf = renderer.RenderUrlAsPdf("https://app.example.com/report/42");
pdf.SaveAs("report.pdf");
A fixed delay is useful for diagnosis but adds latency and can still fail when network time varies. Prefer an application-ready signal or a renderer-supported selector wait. Puppeteer Sharp demonstrates waiting for a selector before calling PdfAsync:
using PuppeteerSharp;
await new BrowserFetcher().DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
await using var page = await browser.NewPageAsync();
await page.GoToAsync("https://app.example.com/report/42", WaitUntilNavigation.Networkidle0);
await page.WaitForSelectorAsync("img.report-chart");
await page.PdfAsync("report.pdf", new PdfOptions { Format = PaperFormat.A4 });
Wait for a meaningful selector, not merely an arbitrary number of seconds. If the image itself is the readiness condition, have the page expose a state such as data-pdf-ready="true" after images decode, then wait for that selector when the library supports it.
Rank #2
- CARTRIDGE-FREE PRINTING — Print lab-quality photos, graphics and creative projects; Get vibrant colors and sharp text with Epson's high-accuracy printhead and Claria ET Premium 6-color inks
- INK BOTTLES — Save on photos1 and creative projects with affordable in-house printing; All-in-one printer allows you to print 4" x 6" photos for about 4 cents each vs. 40 cents with traditional ink cartridges1
- LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; Printer, scanner and copier lets you print up to 6,200 color pages³
- PRINT FOR LONGER — Up to 2 years of ink in the box² (and with every replacement ink set) for fewer out-of-ink frustrations with this wireless printer
- ZERO CARTRIDGE WASTE — Epson EcoTank printer helps reduce the amount of cartridge waste ending up in landfills; Cartridge-free printer uses high-yield ink bottles; Each replacement ink bottle set is equivalent to about 100 individual ink cartridges⁴
4. Check renderer and deployment differences
Capture the exact library and package version, operating system, .NET runtime, process architecture, container base image, and browser or engine version. Chromium/CEF differences can change CSS, font, JavaScript, and image behavior. Iron Software recommends its updated Chrome package as an initial step for rendering mismatches; verify package compatibility before changing production dependencies.
SelectPdf has deployment-specific requirements separate from a bad URL. Its application needs both Select.Pdf.dll and Select.Html.dep; the dependency file may need to be copied manually. The same guide associates access-denied error 5 with execute permissions and error 1260 with group policy blocking its rendering process. Resolve those errors at deployment level before debugging individual images.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →5. Handle timeouts, proxies, and protected resources
When navigation times out, determine whether the renderer can reach the page and image host. SelectPdf documents a default page-load wait of 60 seconds and gives 120 seconds as an example increased timeout; these are SelectPdf settings, not HTML-to-PDF standards.
using SelectPdf;
var converter = new HtmlToPdf();
converter.Options.MaxPageLoadTime = 120;
converter.Options.HttpProxy = new WebProxy("http://proxy.internal:8080");
var pdf = converter.ConvertUrl("https://internal.example.com/report");
pdf.Save("report.pdf");
pdf.Close();
Only increase the timeout after checking DNS, proxy authentication, firewall egress, redirects, and server response time. For protected images, configure the renderer’s documented headers, cookies, or authentication mechanism. Never log bearer tokens or session cookies while collecting diagnostics.
6. Diagnose memory failures caused by large source images
An image displayed at 300 CSS pixels can still be a 12,000-pixel photograph. SelectPdf explains that its conversion path initially creates bitmaps, so source dimensions and image count can exhaust memory even when the PDF layout looks small. This is not a missing-URL problem.
- Resize originals to the largest dimensions the PDF needs.
- Use an appropriate JPEG, PNG, or WebP encoding and remove unnecessary metadata.
- Reduce the number of simultaneously rendered high-resolution images.
- Run a 64-bit process and use the renderer’s x64-optimized build where supported.
- Dispose PDF documents and streams promptly; avoid retaining every page in memory.
If failures appear as OutOfMemoryException only on large jobs, compare source pixel dimensions and concurrent conversions rather than changing relative paths.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRank #3
- SET IT UP ONCE AND PRINT WITH CONFIDENCE. No complicated maintenance. Just easy, reliable printing you can count on.
- INK FOR YEARS. NOT MONTHS. Up to 2 years of ink included. Get thousands of pages of cartridge-free printing. More pages, less hassle
- KEEPS PRINTING WELL AFTER COMPETITORS HAVE QUIT. No complex maintenance. Sharper text, richer colors.[2] Only with HP Smart Tank
- PREMIUM SUPPORT - Strong technical expertise to solve issues faster
- THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.
7. Separate missing images from page splitting
If the image appears but crosses a page boundary, loading succeeded. The problem is pagination. SelectPdf documents KeepImagesTogether = true and the CSS rule page-break-inside: avoid for the image or its container.
.invoice-logo,
.chart-block {
page-break-inside: avoid;
}
var converter = new HtmlToPdf();
converter.Options.KeepImagesTogether = true;
Keeping every image intact can create large blank areas when the remaining space is too small. Apply the rule to important figures or cards rather than the entire document when compact pagination matters.
8. A repeatable troubleshooting workflow
- Classify input: HTML string, local file, or remote URL.
- Write down the resolved resource: absolute URL or normalized file path for each failed image.
- Test from the conversion environment: same host/container, process identity, proxy, DNS, and certificates.
- Inspect bytes and status: confirm the response is an image, not an error document.
- Check readiness: wait for a selector, application-ready state, or a renderer-supported delay.
- Check deployment: package dependencies, permissions, architecture, and engine versions.
- Check memory: source pixel dimensions, image count, and concurrency.
- Check pagination: use keep-together rules only when the image is present but split.
9. Build a useful minimal reproduction
Reduce the case to one HTML file and one image, then preserve the exact failing src, base URL, renderer/package version, operating system, .NET runtime, deployment architecture, and relevant network configuration. Include conversion logs and the complete HTML/CSS/JavaScript needed to reproduce the result. wkhtmltopdf’s issue guidance asks for version, OS/version, and reproducible HTML/CSS/JS; Iron Software requests sample HTML, product version, OS/.NET version, logs, and code. This information distinguishes a bad resource from an engine or deployment defect.
10. Compare renderers by the controls that affect images
| Evaluation axis | Questions to ask |
|---|---|
| Input and base handling | Does it accept strings, files, and URLs? How is a relative image base supplied? |
| Network access | Can it use proxies, headers, cookies, authentication, redirects, and internal DNS? |
| Readiness | Can it wait for a selector, network idle, JavaScript completion, or a controlled delay? |
| Engine support | Which CSS, JavaScript, font, image, and PDF features are supported by the installed engine? |
| Deployment | Which OS, runtime, architecture, native files, permissions, and container packages are required? |
| Diagnostics and memory | Are network and rendering logs available, and how does it behave with large source images? |
SelectPdf’s guide, IronPDF’s Chromium documentation, and Puppeteer Sharp’s browser examples describe different APIs and engines. They do not establish a universal best library or a neutral performance benchmark.
Or skip the browser setup: ScreenshotNeo
If your actual requirement is a clean screenshot or PDF of a URL rather than custom in-process HTML rendering, ScreenshotNeo provides a single HTTP request and an MCP server for AI agents. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
For a URL screenshot, use the API documented at ScreenshotNeo’s documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, device presets and arbitrary viewports, retina scale, PDF paper and margin controls, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers and cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—work with Claude, Cursor, and other MCP clients.
Rank #4
- Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
- No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
- Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
- Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
- The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free. Every feature is available on every plan. Create a free ScreenshotNeo account to try it with no card.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsFrequently Asked Questions
Why does an image work in Chrome but not in my C# PDF?
The PDF process may resolve a different base URL, run under another account, lack proxy or DNS access, miss authentication cookies, or render before JavaScript loads the image. Test the resolved resource from the conversion host.
Should I use a longer delay or wait for a selector?
Use a selector or application-ready condition when the renderer supports it. A fixed delay is mainly a diagnostic or vendor-supported fallback and may be unreliable when network timing changes.
What does a 200 response with a missing image mean?
Inspect the response body and content type. Many protected endpoints return a login page or error HTML with status 200 instead of image bytes.
Why does keeping images together create blank space?
The renderer moves an image that cannot fit on the current page to the next page. That preserves the image but can leave unused space.
Quick Recap
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.

