Most WKPDF failures become straightforward once you separate three cases: the executable cannot start, the renderer starts but produces incomplete output, or the service account is blocked by permissions, libraries, networking, or confinement. Begin by recording the exact binary, version, operating system, wrapper, command, exit code, output path, and stderr. Then reproduce the failure with a tiny local HTML file before adding JavaScript, images, external URLs, and local-file references.
1. Capture the exact failure before changing anything
Use the same account and environment that fails in production. A command that works in your login shell can fail under a web server because its PATH, home directory, temporary directory, and security policy are different.
- Record the executable and version:
wkhtmltopdf --version command -v wkhtmltopdf wkhtmltopdf -H 2>wkhtmltopdf-help.txtThe stable project series is 0.12.6, released June 11, 2020. Record the full version string rather than assuming every installation is that release.
- Record the operating-system release, CPU architecture, container image, wrapper or framework version, and the account that launches the process.
- Save the complete command, input HTML or URL, output path, numeric exit code, and all stderr. Do not copy only the final line of a multi-line error.
- Preserve a minimal, reproducible HTML/CSS/JavaScript test case. The project’s issue process asks for the version, OS, detailed description, and a reproducible test case.
Keep this evidence with each test. Otherwise a package change, different account, or changed URL can make two apparently identical failures impossible to compare.
2. Fix installation and executable errors first
“wkhtmltopdf: command not found”
The shell cannot find a file named wkhtmltopdf. Locate the installed binary, add its directory to the service’s PATH, or configure the wrapper with an absolute path. Check the service environment rather than relying on your interactive shell:
#1 Best Overall
printf '%sn' "$PATH"
command -v wkhtmltopdf
ls -l /full/path/to/wkhtmltopdf
If it is absent, install the build intended for the exact distribution and architecture. Avoid combining a binary and libraries from unrelated distributions.
The file exists but will not start
“No such file or directory” can mean a missing dynamic loader or shared library, not a missing executable. An “Exec format error” usually indicates the wrong CPU architecture. Inspect the binary and the loader reported by the operating system, then install the distribution-specific runtime packages. The project’s “static” builds statically link Qt, but they still require system packages; fontconfig, freetype2, and distribution-specific library versions can determine whether the process starts.
Run the binary directly as the failing service account. If it starts interactively but not from the service, compare environment variables, working directory, home directory, and temporary-directory settings.
Wrapper or framework errors
First run the same command without the wrapper. A wrapper may quote arguments differently, discard stderr, impose a timeout, or invoke another binary. Once the direct command works, print the final argument list produced by the wrapper and compare it with the saved command.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
3. Build a minimal rendering reproduction
Start with a file that has no network dependency:
cat > /tmp/wkpdf-min.html <<'HTML'
<!doctype html>
<html><body><h1>WKPDF test</h1><p>plain text</p></body></html>
HTML
wkhtmltopdf /tmp/wkpdf-min.html /tmp/wkpdf-min.pdf
If this succeeds, add one variable at a time:
- Local CSS and a web font.
- Local images.
- JavaScript that changes the DOM.
- An external URL.
- Local-file references from the HTML.
The first addition that breaks the PDF identifies the class of failure. Keep both the last working file and the first failing file.
JavaScript-generated pages
wkhtmltopdf uses an older Qt WebKit engine. A page can finish its initial load before JavaScript has inserted the content you expect. Test with JavaScript enabled and add a deliberate delay:
Rank #2
wkhtmltopdf --javascript-delay 2000 page.html page.pdf
Increase the delay only for diagnosis. A fixed delay is less reliable than a page that exposes a deterministic completion condition, and long waits increase queue time. If scripts fail because of unsupported modern APIs, a delay will not fix compatibility; use a renderer intended for dynamic JavaScript sites.
Local files and allow-lists
When HTML refers to another local file, review the local-file policy. The command reference provides --enable-local-file-access and allow-list controls. Enable access only for the directories required by the document, and test the exact paths used by the service account. A relative path that works from your shell may resolve elsewhere under a worker process.
4. Diagnose blank, partial, or missing-content PDFs
Blank output
Confirm that the input itself is reachable and that the output file is non-empty. Convert the minimal local file first. If a URL is blank, test that URL from the same host and account; check DNS, proxy and firewall rules, and whether the site requires a certificate chain or authentication unavailable to the renderer. A blank page can also result from JavaScript that never finishes or from a page whose content is hidden until a browser event that Qt WebKit does not implement.
Missing images, styles, or fonts
Inspect every resource URL in the HTML. Relative URLs depend on the document base URL; local paths depend on local-file permissions. Confirm that the service account can read each file and that the output process can access the font cache. Add resources incrementally to identify the first failing request. If an image is generated by JavaScript, test the page after the generation step and use a measured JavaScript delay while investigating.
Incomplete pages and load errors
The command reference includes controls for external links, images, JavaScript, JavaScript delay, and load-error handling. Choose a load-error policy deliberately during troubleshooting rather than allowing a wrapper’s default to hide the cause. Capture stderr for every run; it often identifies a failed URL even when a PDF is still produced.
5. Resolve SSL, DNS, proxy, and network failures
An HTTPS error is not necessarily a wkhtmltopdf defect. Verify the hostname resolves on the rendering host, the firewall permits the destination, and the certificate chain is trusted by the host’s libraries. Test through the same proxy settings and service account used in production. A browser on your workstation may succeed because it has a different trust store, DNS resolver, proxy, or authentication session.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated 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
For private sites, make the authentication mechanism explicit and reproducible. Do not embed long-lived secrets in an HTML file or command line that is logged. If the target blocks the renderer or presents a bot challenge, treat that as an input-site behavior rather than repeatedly increasing delays.
6. Fix server, container, and permission failures
No X server is normally required
wkhtmltopdf is designed to run headlessly; a display service is not normally needed. Installing a virtual X server can hide the real problem and add another moving part. In a container or service, first check missing libraries, fonts, writable temporary storage, the working directory, network access, and confinement rules.
Compare interactive and service environments
Run the minimal conversion as the actual service user, with the same working directory and environment. Verify that:
- The executable and every required shared library are readable.
- The output directory and temporary directory are writable.
- Font files and the font cache are readable and can be refreshed if necessary.
- The process can read the HTML, CSS, images, and any allow-listed local paths.
- DNS and outbound connections are available when the document needs them.
Use an explicit, writable temporary directory if the service’s default is unavailable, and clean temporary files after successful and failed jobs.
AppArmor and SELinux
Mandatory access controls can deny the executable, font cache, temporary directory, application work paths, or network name service even when ordinary Unix permissions look correct. Inspect audit logs for denials at the time of the failure. Adjust the profile to the minimum paths and capabilities required, then retest; do not disable AppArmor or SELinux globally as a diagnostic shortcut.
Output and ownership problems
A successful render can still appear to fail when the process cannot create or replace the destination file. Check parent-directory execute permission, existing-file ownership, disk space, and read-only mounts. Have the wrapper report the exit code and verify the resulting file before returning success to callers.
7. Treat HTML and JavaScript as untrusted input
The project’s warning is explicit: “Do not use wkhtmltopdf with any untrusted HTML.” Unsanitized HTML and JavaScript can lead to complete server takeover. If users supply content, sanitize it, isolate the renderer, restrict filesystem and network access, and apply an AppArmor or SELinux policy tailored to the required paths. Run jobs with a low-privilege account, impose CPU, memory, page-count, and wall-clock limits, and remove temporary data. Never grant broad local-file access merely to make one template work.
8. Make renders reliable in production
- Pin the wkhtmltopdf build and the container or operating-system image; record upgrades as configuration changes.
- Keep a small regression corpus containing local, image-heavy, JavaScript, external-URL, and local-file cases.
- Use deterministic assets and fonts where exact output matters. External resources introduce DNS, certificate, availability, and content-change variables.
- Set an explicit job timeout and capture stderr, exit code, output size, and input identifier in logs.
- Limit concurrency according to available CPU, memory, temporary storage, and network bandwidth. A large JavaScript delay multiplied across workers can exhaust a queue.
- Retry only transient network or storage failures. Repeating a deterministic parse, permission, or unsupported-CSS failure wastes capacity and can amplify load on the target site.
9. Know when to migrate to another renderer
Compare engines against the document you actually need, not only against a successful one-page test.
| Requirement | wkhtmltopdf | Alternative direction |
|---|---|---|
| Controlled reports with mostly HTML/CSS and predictable templates | Can remain suitable after dependencies, fonts, and security controls are pinned. | The project points to WeasyPrint or Prince for controlled report generation. |
| Modern, heavily JavaScript-driven sites | Qt WebKit compatibility and timing can limit results. | The project points to Puppeteer or similar wrappers for dynamic JavaScript sites. |
| Untrusted user HTML | Explicitly warned against without strong isolation and sanitization. | Choose an architecture with a documented sandbox and least-privilege policy. |
| Portable containers | Requires matching libraries, fonts, temporary storage, and confinement rules. | Evaluate the complete dependency footprint and migration cost, not just the command syntax. |
A migration is justified when the engine’s CSS or JavaScript limitations, security maintenance burden, or portability costs exceed the work of converting templates and validating output. Keep representative PDFs from the old renderer so visual differences are intentional and reviewable.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is a clean website screenshot or PDF rather than maintaining a wkhtmltopdf runtime, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL and can return PNG, JPEG, WebP, or PDF. Before capture it can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response identifies the result with X-Page-Verdict and X-Billed headers.
See the ScreenshotNeo API documentation for all options, including full-page and element capture, device and viewport settings, retina scale, PDF paper and margin controls, custom CSS and JavaScript, click and wait conditions, request blocking, headers, cookies, user agent, authorization, timezone, geolocation, transparent backgrounds, resizing, cache TTL, signed links, asynchronous webhooks, bulk capture, usage, and the OpenAPI specification. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
One-call examples
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)
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}`);
Every feature is included on every plan: 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Yearly billing provides two months free. Create a free ScreenshotNeo account to try the API.
Recommended Free Tools
FAQ
What should I attach to a bug report?
Attach the exact version and OS, architecture, wrapper version, complete command, input files, output path, exit code, stderr, and a minimal reproducible case. Include whether the failure occurs only under a service account or confinement profile.
Best Value
Does a static build remove all dependency concerns?
No. Qt may be statically linked, but the process still depends on system packages and runtime configuration such as fontconfig, freetype2, and distribution-specific libraries.
How can I tell whether a retry is safe?
Retry a job only when logs indicate a transient network, storage, or capacity problem. A missing library, denied path, unsupported page feature, or deterministic parse error requires a fix, not repeated attempts.
Bottom line
Diagnose wkhtmltopdf in layers: prove the binary starts, reduce rendering to a local minimal file, add resources one at a time, then investigate the service account’s libraries, permissions, network, and confinement policy. Sanitize and isolate any untrusted HTML. If the required pages depend on modern JavaScript or the runtime is too costly to maintain, evaluate a renderer designed for that workload—or use ScreenshotNeo when you need an API-managed capture instead of a browser installation.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Frequently Asked Questions
What should I attach to a bug report?
Attach the exact version and OS, architecture, wrapper version, complete command, input files, output path, exit code, stderr, and a minimal reproducible case. Include whether the failure occurs only under a service account or confinement profile.
Does a static build remove all dependency concerns?
No. Qt may be statically linked, but the process still depends on system packages and runtime configuration such as fontconfig, freetype2, and distribution-specific libraries.
How can I tell whether a retry is safe?
Retry a job only when logs indicate a transient network, storage, or capacity problem. A missing library, denied path, unsupported page feature, or deterministic parse error requires a fix, not repeated attempts.
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.
Free tools Windows power users keep installed
One-click scans. No signup required.

