The dreaded Exit with code 1 message from wkhtmltopdf has derailed countless deployments. When this error appears, the tool provides minimal context, leaving developers to piece together the cause from cryptic network errors and signal codes. This comprehensive reference covers every common wkhtmltopdf exit code, their root causes, and why the abandoned state of the project means these issues will never receive official fixes.
The Problem
wkhtmltopdf returns non-zero exit codes when PDF generation fails. The most common is exit code 1, which the tool uses as a catch-all for various failure conditions. However, developers also encounter exit codes -6, -11, and 139, each indicating different failure modes. Because wkhtmltopdf was archived on January 2, 2023, these error behaviors are now frozen permanently.
The exit code by itself tells you almost nothing. A code of 1 might mean a network timeout, a missing CSS file, an SSL handshake failure, or an inaccessible local resource. The actual cause is buried in the accompanying error message, which wkhtmltopdf outputs to stderr.
Exit Code Reference
| Exit Code | Signal | Meaning |
|---|---|---|
| 1 | N/A | General failure (network error, resource not found, etc.) |
| -6 | SIGABRT | Process aborted (often QXcbConnection errors) |
| -11 | SIGSEGV | Segmentation fault (memory access violation) |
| 134 | SIGABRT (128+6) | Abort signal on some systems |
| 139 | SIGSEGV (128+11) | Segmentation fault (alternative encoding) |
Exit Code 1: Network Errors
Exit code 1 encompasses the broadest category of failures. The error message following the exit code identifies the specific problem.
ContentNotFoundError
Exit with code 1 due to network error: ContentNotFoundError
This error occurs when wkhtmltopdf cannot load a resource referenced in your HTML. Common causes include:
- CSS stylesheets returning 404
- Image files not found
- JavaScript files missing
- Fonts failing to load
- Relative paths that resolve incorrectly on the server
A GitHub issue from 2014 documents this error appearing even with the --load-error-handling ignore flag:
"With v0.12.1, PDFKit wrapper and --load-error-handling ignore: Exit with code 1 due to network error: ContentNotFoundError"
— GitHub Issue #2051
The underlying problem is that wkhtmltopdf attempts to fetch resources from URLs, but the server context during PDF generation differs from the browser context. A resource accessible at http://localhost:3000/styles.css during development may not be reachable when wkhtmltopdf runs on a production server.
HostNotFoundError
Exit with code 1 due to network error: HostNotFoundError
This error appears when DNS resolution fails for a hostname referenced in your HTML. Developers report intermittent failures:
"I am using wkhtmltopdf 0.12.2.1 (with patched qt) 64 bit version and I am using Pdfkit to execute the generation. I am randomly getting the Exit with code 1 due to network error: HostNotFoundError"
— GitHub Issue #2532
The randomness suggests DNS caching issues or network timeouts. Because wkhtmltopdf spawns as an external process, it may not inherit the same DNS configuration as your application.
ProtocolUnknownError
Exit with code 1 due to network error: ProtocolUnknownError
Newer versions of wkhtmltopdf (0.12.5+) disallow file:// URLs by default for security reasons. If your HTML references local files:
<link rel="stylesheet" href="file:///var/www/styles/main.css">
<img src="file:///var/www/images/logo.png">
You must pass --enable-local-file-access to allow these references. However, enabling this flag introduces security risks if processing untrusted HTML.
SslHandshakeFailedError
Exit with code 1 due to network error: SslHandshakeFailedError
wkhtmltopdf's Qt WebKit engine uses outdated SSL/TLS implementations. Modern servers requiring TLS 1.2 or TLS 1.3 may reject connections from wkhtmltopdf:
"Loading images from a web server with TLSv1 works, but on a modern server with TLS 1.2, it breaks (though not for all resources)."
— Dev.to article on wkhtmltopdf network errors
This issue will never be fixed because wkhtmltopdf's SSL stack is frozen in its archived state.
ConnectionRefusedError
Exit with code 1 due to network error: ConnectionRefusedError
Error: Failed to load [URL], with network status code 1 and http status code 0 - Connection refused
This error indicates that wkhtmltopdf attempted to connect to a server that actively refused the connection. Common scenarios:
- Localhost URLs when the development server is not running
- Internal URLs blocked by firewall rules
- Docker containers unable to reach host network services
TimeoutError
Exit with code 1 due to network error: TimeoutError
wkhtmltopdf has limited timeout controls. Network requests that take too long cause this error. The tool may hang indefinitely on slow resources:
"Currently there is no way to control how long wkhtmltopdf will wait for media to load."
— GitHub Issue #1888
Some users report wkhtmltopdf running for 28+ minutes consuming 99% CPU before finally timing out.
ContentAccessDenied
Exit with code 1 due to network error: ContentAccessDenied
The server returned a 403 Forbidden response for a requested resource. This often occurs in containerized environments where the wkhtmltopdf process runs under a different user context than the web server.
Exit Code -6: QXcbConnection Errors
Exit code -6 corresponds to SIGABRT (abort signal). The most common cause is the infamous QXcbConnection error:
QXcbConnection: Could not connect to display
wkhtmltopdf exited with non-zero code -6
Root Cause
wkhtmltopdf was designed for desktop systems with X11 display servers. When running on headless servers without a display, the Qt libraries attempt to connect to an X server that does not exist.
The official wkhtmltopdf documentation states:
"This program requires an X11 server to run."
However, this is only partially true. The version of wkhtmltopdf matters significantly:
- Distro packages (apt-get, yum): Compiled against standard Qt without headless patches. These require X11 or xvfb.
- Official binaries (wkhtmltopdf.org): Compiled with patched Qt that supports headless operation.
A GitHub issue documents the confusion:
"The CentOS package is like the Ubuntu one: it's compiled without the patched version of Qt provided by wkhtmltopdf team. Without patched Qt, wkhtml can't run in a truly headless mode."
— GitHub Issue #2932
Solutions for QXcbConnection Errors
Option 1: Use xvfb (Virtual Framebuffer)
Install xvfb and wrap wkhtmltopdf calls:
apt-get install xvfb
xvfb-run wkhtmltopdf input.html output.pdf
Or use the --auto-servernum flag to avoid display conflicts:
xvfb-run --auto-servernum wkhtmltopdf input.html output.pdf
Option 2: Download Official Binaries with Patched Qt
Replace distro packages with official binaries from the wkhtmltopdf releases page:
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
dpkg -i wkhtmltox_0.12.6-1.focal_amd64.deb
Option 3: Set QT_QPA_PLATFORM Environment Variable
For Qt5-based builds:
export QT_QPA_PLATFORM=offscreen
wkhtmltopdf input.html output.pdf
Docker Considerations
In Docker containers, you typically need both the patched binary and font packages:
FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y \
wget \
fontconfig \
libfreetype6 \
libjpeg62-turbo \
libpng16-16 \
libx11-6 \
libxcb1 \
libxext6 \
libxrender1 \
xfonts-75dpi \
xfonts-base
RUN wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.bullseye_amd64.deb \
&& dpkg -i wkhtmltox_0.12.6-1.bullseye_amd64.deb \
&& rm wkhtmltox_0.12.6-1.bullseye_amd64.deb
Note: This Dockerfile pulls from an archived repository. No security updates will be available.
Exit Code -11 / 139: Segmentation Faults
Exit code -11 indicates a segmentation fault (SIGSEGV). On some systems, this appears as exit code 139 (128 + 11). This is wkhtmltopdf's most severe crash type.
The exit status code '139' says something went wrong: Segmentation fault (core dumped)
Wkhtmltopdf failed (error code: -11)
Common Triggers
Large Documents with Headers/Footers
When generating PDFs over 200 pages with headers and footers, wkhtmltopdf can exhaust file handles:
"When you try to generate a big pdf (over 200 pages) with header and footer, you get an error -11. It is a limitation of max handle file per process (default is 256). The wkhtmltopdf opens for each page the header and the footer."
— Odoo Forum
CSS Edge Cases
Certain CSS values trigger rendering crashes:
"In some cases, changing a CSS property like line-height from 1.3 to 1.4 can make the bug disappear, showing how sensitive the rendering engine can be to specific style values."
— GitHub Issue #2684
Empty Last Page
Documents where the last page contains only margins and no content can crash:
"This error occurs when there is only empty content (such as margin) to be drawn on the last page."
— GitHub Issue #2711
Memory Exhaustion
Under high load, wkhtmltopdf can consume unlimited memory:
"Once launched, you cannot tell or control how much resources (memory in particular) wkhtmltopdf consumes - it's a black box."
— Wkhtmltopdf Considered Harmful
Potential Mitigations
Increase File Handle Limits
ulimit -n 10000
wkhtmltopdf input.html output.pdf
Or permanently in /etc/security/limits.conf:
* soft nofile 65535
* hard nofile 65535
Increase Memory Limits
Some users report success setting high memory limits:
"The soft had to be set to 1GB and the hard to about 1.5GB. Once those numbers were set high, the issue stops happening."
— GitHub Issue #19160
Remove Problematic Options
If using --disable-smart-shrinking, try removing it. If using complex headers/footers, simplify them.
Avoid Empty Last Pages
Add padding content to ensure the last page has renderable content:
<div style="page-break-inside: avoid; min-height: 1px;"> </div>
Socket and Hanging Errors
wkhtmltopdf can hang indefinitely when encountering certain network conditions:
wkhtmltopdf hangs on network errors
A 2015 GitHub issue documents this:
"On Ubuntu systems, wkhtmltopdf can hang on network errors. After a socket connection is established, the process freezes while waiting for network responses."
— GitHub Issue #2254
ProcessTimedOutException
When using wrappers like Snappy or PDFKit, the parent process may timeout while waiting for wkhtmltopdf:
ProcessTimedOutException: The process exceeded the timeout of 1800 seconds
The timeout behavior is inconsistent:
"Sometimes PDF generation works fine in 2-3 seconds, but other times it fails after 60 seconds with a ProcessTimedOutException error."
— GitHub Issue #885
There is no reliable way to set internal timeouts for wkhtmltopdf resource loading. External process timeouts are the only option.
Who Is Affected
These exit codes affect developers across multiple scenarios:
Operating Systems
- Linux servers (most common deployment target)
- Docker containers
- macOS development environments
- Windows servers (less common)
Frameworks and Languages
- Python with pdfkit or WeasyPrint wrappers
- Ruby with wicked_pdf or PDFKit
- PHP with Snappy or phpwkhtmltopdf
- Node.js with node-wkhtmltopdf
- .NET with DinkToPdf, Rotativa, or NReco.PdfGenerator
- Java with various wkhtmltopdf wrappers
Use Cases
- Invoice and report generation
- Certificate generation
- Web page archiving
- E-commerce order confirmations
- Automated document workflows
Evidence from the Developer Community
The persistence and severity of these errors is documented across multiple platforms.
Stack Overflow
A 2022 question with multiple answers shows ongoing frustration:
"How to solve 'wkhtmltopdf reported an error: Exit with code 1 due to network error: ProtocolUnknownError'"
— Stack Overflow
GitHub Issues
The wkhtmltopdf repository accumulated thousands of issues before being archived. Network errors alone generated hundreds of reports:
- Issue #2051 - ContentNotFoundError (2014, still open)
- Issue #2532 - HostNotFoundError (2015, still open)
- Issue #4957 - Error code -11 (2021, still open)
- Issue #2037 - QXcbConnection (2014, still open)
Blog Posts and Documentation
The Theodo engineering blog published a two-part series documenting their struggles:
"One Year With Wkhtmltopdf: One Thousand Problems, One Thousand Solutions"
— Theodo Blog
Rebased published a critical analysis:
"Wkhtmltopdf Considered Harmful"
— Rebased Blog
Timeline of Abandonment
| Date | Event |
|---|---|
| April 2013 | Google forks WebKit into Blink |
| 2015 | Qt deprecates QtWebKit |
| 2016 | Qt removes QtWebKit from the framework |
| June 2020 | wkhtmltopdf 0.12.6 released (final version) |
| August 2022 | CVE-2022-35583 (SSRF vulnerability) disclosed |
| January 2, 2023 | wkhtmltopdf repository archived |
| July 10, 2024 | wkhtmltopdf organization marked archived |
The project has been effectively abandoned since 2020, with no releases in over five years. The archived status means:
- No bug fixes
- No security patches
- No compatibility updates
- No community support from maintainers
Root Cause Analysis
wkhtmltopdf's exit codes stem from fundamental architectural limitations:
Outdated Rendering Engine
wkhtmltopdf uses Qt WebKit, which Qt deprecated in 2015 and removed in 2016. The rendering engine is frozen at approximately Chrome 18-20 capability (circa 2012). Modern CSS features, JavaScript APIs, and TLS protocols are not supported.
External Process Architecture
wkhtmltopdf runs as a separate process, creating isolation issues:
- Different network context than calling application
- Different DNS resolution
- Different SSL/TLS certificate stores
- Different file system permissions
- No memory limits or resource controls
Qt Dependency Fragmentation
The requirement for a "patched Qt" creates a split ecosystem:
- Distro packages: Standard Qt, requires X11/xvfb
- Official binaries: Patched Qt, supports headless
- User confusion about which version they have
No Active Maintenance
Since archiving, these issues cannot be fixed upstream. Workarounds are the only option, and even those may break with OS updates.
Attempted Workarounds
Workaround 1: --load-error-handling ignore
Approach: Tell wkhtmltopdf to continue despite resource loading failures.
wkhtmltopdf --load-error-handling ignore input.html output.pdf
Limitations:
- Does not work for all error types
- PDF may render with missing content
- Still fails on ContentNotFoundError in some versions
Workaround 2: Use Absolute Paths and Inline Resources
Approach: Eliminate network requests by inlining all CSS, JavaScript, and images.
<style>
/* Inline all CSS instead of external references */
body { font-family: Arial, sans-serif; }
</style>
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." />
Limitations:
- Increases HTML size significantly
- Difficult to maintain
- Base64 images are 33% larger than originals
Workaround 3: Local File Server
Approach: Run a local HTTP server that wkhtmltopdf can access.
# Serve files on localhost for wkhtmltopdf to access
import http.server
import threading
def start_server():
server = http.server.HTTPServer(('localhost', 8888), http.server.SimpleHTTPRequestHandler)
server.serve_forever()
thread = threading.Thread(target=start_server, daemon=True)
thread.start()
Limitations:
- Adds deployment complexity
- Port conflicts possible
- Firewall considerations in containers
Workaround 4: xvfb Wrapper
Approach: Use virtual framebuffer for headless operation.
#!/bin/bash
xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" wkhtmltopdf "$@"
Limitations:
- Additional dependency to install
- Slight performance overhead
- Does not solve rendering or network issues
A Different Approach: IronPDF
For development teams experiencing persistent wkhtmltopdf errors, IronPDF provides an alternative architecture that eliminates the external process dependency and its associated error modes.
Why IronPDF Avoids Exit Code Errors
IronPDF embeds a Chromium rendering engine directly in the .NET process. This architectural difference eliminates entire categories of wkhtmltopdf failures:
- No external process: No exit codes, no signal handling, no process spawning failures
- No X11 dependency: Chromium runs headless natively without xvfb
- Modern TLS: Full TLS 1.2 and 1.3 support
- Network context sharing: Same DNS, same proxy settings, same SSL certificates as parent application
- Memory management: Controlled by .NET garbage collector, not an external black box
- Regular updates: Security patches and bug fixes through normal NuGet updates
Code Example: Replacing wkhtmltopdf
The following example shows how to convert HTML to PDF without external processes or exit codes:
using IronPdf;
public class PdfService
{
public byte[] ConvertHtmlToPdf(string htmlContent)
{
// No external process - Chromium runs in-process
// No exit codes to handle
var renderer = new ChromePdfRenderer();
// Network requests use the same context as your application
// Same DNS, same proxy, same TLS settings
renderer.RenderingOptions.Timeout = 60; // Seconds, not infinite
// CSS and JavaScript execute in modern Chromium
// Flexbox, Grid, calc(), CSS variables all work
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.RenderDelay = 500;
using (var pdf = renderer.RenderHtmlAsPdf(htmlContent))
{
return pdf.BinaryData;
}
}
public byte[] ConvertUrlToPdf(string url)
{
var renderer = new ChromePdfRenderer();
// TLS 1.2/1.3 supported - no SslHandshakeFailedError
// HTTP/2 supported
using (var pdf = renderer.RenderUrlAsPdf(url))
{
return pdf.BinaryData;
}
}
}
Code Example: Error Handling Without Exit Codes
Instead of parsing stderr for exit codes, IronPDF throws .NET exceptions:
using IronPdf;
using System;
public class RobustPdfService
{
public byte[] SafeConvert(string html)
{
try
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.Timeout = 30;
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
return pdf.BinaryData;
}
}
catch (IronPdf.Exceptions.IronPdfRenderException ex)
{
// Specific rendering failure - check ex.Message for details
// No need to parse exit codes or stderr output
throw new PdfGenerationException("Rendering failed", ex);
}
catch (TimeoutException ex)
{
// Clear timeout handling - no hanging processes
throw new PdfGenerationException("Timeout during rendering", ex);
}
catch (Exception ex)
{
// Generic handling - still better than signal parsing
throw new PdfGenerationException("PDF generation failed", ex);
}
}
}
Code Example: Docker Without xvfb
IronPDF runs in Docker containers without X11 or xvfb:
FROM mcr.microsoft.com/dotnet/aspnet:8.0
# IronPDF dependencies - no xvfb needed
RUN apt-get update && apt-get install -y \
libc6 \
libgcc1 \
libgssapi-krb5-2 \
libicu72 \
libssl3 \
libstdc++6 \
zlib1g \
libgdiplus \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "YourApp.dll"]
// No special configuration for headless - it just works
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello from Docker</h1>");
pdf.SaveAs("/app/output/document.pdf");
API Reference
- ChromePdfRenderer - Main rendering class
- RenderingOptions - Configuration options
- Docker Deployment Guide - Container setup
- Troubleshooting Guide - Common issues and solutions
Migration Considerations
Licensing
IronPDF is commercial software with per-developer licensing. A free trial is available for evaluation. Teams accustomed to wkhtmltopdf's open-source model should weigh the licensing cost against the engineering time spent handling exit codes, xvfb configuration, and security vulnerabilities.
API Differences
| wkhtmltopdf | IronPDF |
|---|---|
| External process with exit codes | In-process library with exceptions |
| xvfb required for headless | Native headless support |
--load-error-handling flags |
RenderingOptions properties |
| Parse stderr for errors | Catch .NET exceptions |
| Qt WebKit (Chrome ~18) | Chromium (current) |
What You Gain
- No exit code handling or stderr parsing
- No xvfb or X11 dependencies
- Modern CSS (Flexbox, Grid, calc(), variables)
- Current TLS support
- Regular security updates
- Controlled resource consumption
- Clear exception-based error handling
What to Consider
- Commercial licensing cost
- Different API patterns require code changes
- Slightly different rendering output (Chromium vs Qt WebKit)
- Larger deployment footprint due to embedded Chromium
Conclusion
wkhtmltopdf's exit codes represent a symptom of deeper architectural problems: an abandoned rendering engine, external process isolation, and dependency on deprecated Qt libraries. Exit code 1 with network errors, exit code -6 with QXcbConnection failures, and exit code -11 segmentation faults will never receive official fixes. Development teams experiencing these errors have two choices: invest engineering time in workarounds for unmaintained software, or migrate to an actively developed alternative that eliminates these failure modes entirely.
Jacob Mellor has spent 25+ years building developer tools and currently serves as CTO at Iron Software.
References
- Exit with code 1 due to network error: ContentNotFoundError - GitHub Issue #2051{:rel="nofollow"} - Original ContentNotFoundError report
- Exit with code 1 due to network error: HostNotFoundError - GitHub Issue #2532{:rel="nofollow"} - HostNotFoundError documentation
- Wkhtmltopdf failed (error code: -11) - Odoo Forum{:rel="nofollow"} - Exit code -11 analysis
- QXcbConnection: Could not connect to display - GitHub Issue #2037{:rel="nofollow"} - X11 display errors
- Updated my Ubuntu Server and got "QXcbConnection: Could not connect to display" - GitHub Issue #2932{:rel="nofollow"} - Patched Qt explanation
- wkhtmltopdf hangs on network errors - GitHub Issue #2254{:rel="nofollow"} - Socket hanging documentation
- Solve network errors with PDFKit and wkhtmltopdf - Dev.to{:rel="nofollow"} - TLS compatibility issues
- Wkhtmltopdf Considered Harmful - Rebased Blog{:rel="nofollow"} - Critical analysis
- One Year With Wkhtmltopdf - Theodo Blog{:rel="nofollow"} - Real-world experience
- How to solve wkhtmltopdf error - Stack Overflow{:rel="nofollow"} - Community Q&A
- wkhtmltopdf is now abandonware - Doppio Documentation{:rel="nofollow"} - Abandonment status
For IronPDF documentation and tutorials, visit ironpdf.com.
Top comments (0)