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

Exit code 127 usually means Python could not start wkhtmltopdf: either the executable is not on the process’s PATH, or the operating system cannot load it because a required shared library or loader is missing. Start by checking the exact executable Python can find, then run that executable directly and inspect stderr. Installing another package before identifying which of those failures you have can waste time or leave the real problem untouched.

What exit code 127 means in a Python PDF job

Exit status 127 is commonly associated with a command that cannot be found or launched. Python documents 127 as the status used when an executable cannot be found; a missing shared library can produce the same status when the binary is present but its runtime loader cannot start it. A Microsoft Q&A report, for example, describes exit code 127 alongside a missing libjpeg.so.62 library (Microsoft Q&A, May 5, 2025).

That distinction matters: if the executable is absent, fix installation or PATH; if it exists but cannot load, fix the host’s libraries, loader, architecture, or libc compatibility. The numeric code alone does not identify which cause applies. Read stderr and test the binary outside the PDF wrapper before changing the application.

Check the exact binary Python can launch

Run this in the same runtime, container, virtual machine, or service environment where PDF generation fails. A developer shell can have a different PATH and different libraries from a web worker.

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.
import shutil
import subprocess

exe = shutil.which("wkhtmltopdf")
if not exe:
    raise RuntimeError("wkhtmltopdf is not on PATH")

check = subprocess.run(
    [exe, "--version"],
    text=True,
    capture_output=True,
)
print("executable:", exe)
print("return code:", check.returncode)
print("stdout:", check.stdout)
print("stderr:", check.stderr)

shutil.which() checks what the current process can resolve through PATH. Python’s subprocess documentation recommends using a fully qualified executable path for reliability and documents executable lookup and return-code behavior (Python subprocess documentation). If which returns None, Python cannot locate the command in its current environment.

If the command is found, the --version test is still important. A return code of zero with a version string shows that the program can start in that environment; a loader or library error in stderr points to a runtime dependency problem. Record the executable path and complete stderr, not just the final Python exception.

Use an explicit path with subprocess

Once you know the path, call it directly. Passing an argument list avoids shell parsing and makes the executable being tested explicit.

from pathlib import Path
import subprocess

exe = "/usr/bin/wkhtmltopdf"  # Replace with the path found in your runtime.
html_file = Path("report.html").resolve()
pdf_file = Path("report.pdf").resolve()

result = subprocess.run(
    [exe, str(html_file), str(pdf_file)],
    text=True,
    capture_output=True,
)

print("return code:", result.returncode)
print("stdout:", result.stdout)
print("stderr:", result.stderr)
result.check_returncode()

Use paths that exist in the process’s filesystem. For an HTML string rather than a file, use the wrapper’s supported input mode or write a controlled temporary file; do not assume the command accepts a Python string as a filename.

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

Configure wrappers to use the same executable

Some Python integrations invoke the bare name wkhtmltopdf by default. The django-wkhtmltopdf settings provide an explicit command and environment override (django-wkhtmltopdf settings). Set its command option to the absolute executable path you just tested when the default lookup is wrong. Make sure the service process has the environment values required by the binary; a setting in an interactive shell does not automatically apply to a worker or deployment.

Identify the failure from stderr

Observed output Likely cause Next action
sh: wkhtmltopdf: not found, or shutil.which() returns None The executable is missing or absent from the process PATH. Install a build for the host, or configure the wrapper/subprocess call with the installed absolute path.
error while loading shared libraries: lib….so…: cannot open shared object file A required runtime library is not installed or not visible to the dynamic loader. Install the matching distribution’s library package. Where the host uses a linker cache, refresh it as appropriate; then retry the direct version check.
No such file or directory even though the binary file exists The binary may target a different architecture or ELF loader, or use an incompatible libc. Check the image architecture and libc; use a compatible build rather than treating this as a simple PATH problem.
Fontconfig/font errors, missing glyphs, or blank-looking output A stripped-down image may lack fonts or Fontconfig configuration. Install suitable fonts and configure FONTCONFIG_PATH if the deployment’s layout requires it.

A useful diagnostic sequence is: find the executable, run --version, then run a minimal PDF conversion and inspect its stderr. If the version test fails, do not debug the HTML template yet: first make the executable start reliably.

Choose a wkhtmltopdf build that matches the host

The wkhtmltopdf project’s stable series is 0.12.6, released June 11, 2020. Its download page lists distribution-specific builds and explains why generic Linux binaries were removed: libc and system-library differences made them unreliable. The project specifically notes that generic binaries do not work on Alpine, which uses musl libc (wkhtmltopdf downloads and platform notes).

Do not assume a binary that works on a developer’s Debian or Ubuntu machine will also run in an Alpine image, a different CPU architecture, or a managed cloud runtime. Match the executable to the operating system and architecture of the deployed image, and pin the image and binary together in deployment documentation so they are upgraded and tested as a pair.

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

“Static” does not mean dependency-free

The project warns that a static build only links Qt in that manner; the remaining system packages still need to be installed. The host may still need libraries, Fontconfig, freetype2, and fonts. Treat an error naming a missing .so file as evidence about a specific runtime dependency, not as a reason to download a different binary blindly.

For example, a Microsoft Q&A response to the reported missing libjpeg.so.62 case listed libjpeg62-turbo, libxrender1, libxext6, xfonts-base, and xfonts-75dpi as example dependencies. That list is specific to that incident and environment, not a universal install command or package set (Microsoft Q&A incident). Package names and availability vary by distribution and release.

Fix PATH and dependency failures in Docker or cloud runtimes

Minimal containers and managed runtimes often omit tools and libraries present on a developer workstation. Ensure the deployed artifact includes the executable, its compatible shared libraries, and fonts, and ensure that the service process can see the paths where they are placed. Test in the same base image or runtime configuration used for deployment.

For a Docker image

  1. Check the image’s operating system, architecture, and libc. Do not copy a glibc-targeted binary into an Alpine/musl image and expect it to start.
  2. Install or package the compatible executable and dependencies. Use distribution-appropriate package sources and names; an Ubuntu installation command is not a general fix for Alpine or another distribution.
  3. Verify from inside the built image. Run which wkhtmltopdf or an equivalent PATH check, then /absolute/path/wkhtmltopdf --version. Confirm fonts and a small PDF conversion as well.
  4. Keep deployment versions together. Record the image base and wkhtmltopdf build so a rebuild does not silently change their compatibility.

For Lambda-style packaging

The official wkhtmltopdf project’s Lambda example places the executable and its supporting files in a layer and sets environment variables before invoking it: LD_LIBRARY_PATH=/opt/lib and FONTCONFIG_PATH=/opt/fonts (project downloads and Lambda example). In that pattern, the executable is under /opt/bin, libraries under /opt/lib, and fonts under /opt/fonts. Adapt paths to the actual layer layout; the names only help if the files are present there and readable by the runtime.

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

Unpack and test the layer in the matching base image before deploying. For managed services where you cannot install packages at runtime, bake the executable and dependencies into an image or deployment artifact, or use the platform’s supported startup packaging mechanism. The exact package-install procedure depends on the host and is not interchangeable across distributions.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make the capture safe and diagnosable

wkhtmltopdf renders HTML and can execute or load content as part of rendering. The project explicitly warns: “Do not use wkhtmltopdf with any untrusted HTML – be sure to sanitize any user-supplied HTML/JS, otherwise it can lead to complete takeover of the server it is running on!” (wkhtmltopdf security warning). Do not pass arbitrary user-controlled HTML or JavaScript to a privileged renderer. Sanitize input and run rendering with least privilege, restricted filesystem access, and limited process permissions.

The project provides AppArmor guidance for constraining filesystem access and command execution; AppArmor is relevant on Ubuntu, Debian, and SUSE systems, while SELinux is used on Red Hat-family systems (wkhtmltopdf AppArmor guidance). Choose isolation appropriate to the host rather than assuming that changing the Python call alone makes untrusted rendering safe.

If you need to report a wkhtmltopdf issue, include the version, operating-system version, command, full stderr, and a minimal reproducible HTML/CSS/JavaScript case, as requested by the project’s support guidance (wkhtmltopdf support). Redact secrets, cookies, authorization headers, and private page content before sharing logs or examples.

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

Or skip the browser setup

If you need website screenshots or PDFs rather than a local wkhtmltopdf rendering pipeline, ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. For example, this cURL request saves a screenshot of Stripe as WebP:

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

See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed before capture, along with known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and billing result. Its MCP server gives AI agents tools for taking screenshots, getting page information, and capturing PDFs. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Frequently Asked Questions

Does exit code 127 always mean wkhtmltopdf is missing?

No. It can also mean the executable exists but its loader cannot start it because a required shared library or compatible runtime is missing. The error text in stderr distinguishes these cases.

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.

Why does wkhtmltopdf work on my computer but fail in Docker?

The container can have a different PATH, CPU architecture, libc, shared libraries, or font configuration from the host. Test the executable inside the built image, not only on the machine building it.

Is wkhtmltopdf suitable for rendering arbitrary user-submitted HTML?

No. The project warns that untrusted HTML or JavaScript can create a server-compromise risk. Sanitize input and isolate the renderer with restricted permissions.

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.