How to Fix wkhtmltoimage SSL Handshake Errors
Diagnose wkhtmltoimage SSL errors by separating certificate trust, TLS runtime, failed page resources, and HTTP access problems.
An “SSL handshake error” from wkhtmltoimage is a symptom, not a diagnosis. The cause could be a certificate trust problem, an incompatible TLS library loaded by the binary, a failing CSS or image host, or an HTTP access error that is not a TLS failure at all. Start by saving the complete error output and recording the exact binary, operating system, package source, target URL, and whether the main page or a linked resource failed.
The wkhtmltopdf project is archived, so treat fixes as environment-specific checks. Historical release notes and issue reports can help explain a symptom, but they do not establish that a particular flag or replacement library will fix every current site. See the archived project and its release history.
1. Capture enough information to diagnose it
Run the same command that fails, preserving standard error. Record:
- The full command line and complete stderr, including lines before and after the SSL warning.
wkhtmltoimage --version, including whether the output sayswith patched qt.- Operating system and version, package source, and whether the process runs in a container or under a service account.
- The target URL, when the failure occurs, and whether a browser on the same machine can open it.
- Whether the failed URL is the main document or a CSS, JavaScript, image, font, iframe, or redirected request.
wkhtmltoimage --version
wkhtmltoimage --log-level info 'https://example.com/' /tmp/page.png 2>/tmp/wkhtmltoimage.stderr
cat /tmp/wkhtmltoimage.stderr
Change the output path if needed. Some builds support different logging options; if --log-level is rejected, omit it and capture stderr anyway. Do not discard output with --quiet while diagnosing.
2. Identify which request failed
First test whether the main document loads without its remote dependencies. Save a minimal local file and render it:
cat > /tmp/minimal.html <<'HTML'
<!doctype html>
<html><head><meta charset="utf-8"><title>Local test</title></head>
<body><h1>Local render works</h1></body></html>
HTML
wkhtmltoimage /tmp/minimal.html /tmp/minimal.png
If the local file succeeds but the URL fails, investigate network access, redirects, the target server, and its certificate chain. If the page loads but one asset does not, inspect that asset host separately. A project report describes CDN resource failures alongside SSL warnings and an overall network error; it is a reason to isolate dependencies, not proof that the main page’s handshake failed. See the resource-loading issue report.
Use a command-line TLS client, if installed, to inspect each relevant host and its response. Follow redirects and test the exact asset URL, not just the page hostname. A successful check from a different machine does not prove the wkhtmltoimage process has the same DNS, proxy, trust store, or runtime libraries.
curl -vIL 'https://example.com/'
# Repeat with the exact failing CSS, image, font, script, or iframe URL.
3. Separate certificate trust from TLS runtime problems
Certificate-chain and trust-store checks
If the log indicates certificate validation, confirm the site serves a valid chain and that the process can read the expected CA certificates. Check from the same host, container, and service account that runs wkhtmltoimage. A command that works in an interactive shell may fail in a minimal container or under a different account.
- Confirm the system CA bundle exists and is readable inside the runtime environment.
- Check that the server sends its intermediate certificates and that the certificate hostname matches the requested hostname.
- Check the system clock; an incorrect clock can make certificates appear expired or not yet valid.
- If an enterprise proxy intercepts TLS, ensure its root CA is intentionally installed in the trust store used by this process.
- For a private CA, configure the appropriate trust store for the operating system and Qt build rather than trusting an arbitrary certificate.
Qt documents that Unix root certificates can be loaded on demand and describes configuring additional CA certificates in its SSL documentation. The exact behavior depends on the Qt version and how the application was packaged.
Qt/OpenSSL runtime checks
Messages such as QSslSocket: cannot resolve SSL_load_error_strings point toward a TLS runtime or symbol-compatibility problem, rather than simply an untrusted site certificate. Check which Qt and OpenSSL libraries the exact binary loads and whether they match the build’s expectations. Avoid replacing system libraries blindly: doing so can break unrelated software, and the available reports do not show that swapping OpenSSL is a universal fix.
The project release history records historical OpenSSL-related changes. An issue documents a 0.12.5 report with unresolved OpenSSL symbols. These records make build and runtime compatibility a sensible diagnostic branch, not a promise that upgrading or installing a particular library resolves every case: release history and issue #3945.
Qt’s Linux and Windows deployment guidance for Qt 5.14 specifies OpenSSL 1.1.1 for that Qt release and notes that OpenSSL libraries are not automatically deployed. Do not apply that requirement to every wkhtmltoimage package or platform; identify the Qt version and packaging of your binary first. See Qt 5.14 OpenSSL support guidance.
4. Rule out HTTP errors and access controls
A response such as 403 Forbidden, 401 Unauthorized, or an access-denied page is an HTTP or policy response. It does not, by itself, establish that a TLS handshake failed. Check credentials, cookies, proxy configuration, redirects, IP allowlists, bot controls, and server rules. A historical report involving wkhtmltopdf 0.12.6 and patched Qt includes a 403 response; treat it as an example of why status codes need their own branch of diagnosis: the 403 report.
Likewise, UnknownNetworkError is a broad network failure description. Read the surrounding log and identify the actual request and response before changing TLS settings.
5. Test one change at a time
- Reproduce the problem with the original command and save its output.
- Try the main document with remote dependencies removed or on a minimal local page.
- Test each failing resource URL and redirect separately from the same runtime environment.
- Verify the process’s CA store and certificate chain if the evidence points to validation.
- Inspect the binary’s Qt/OpenSSL runtime if the log points to missing symbols or library loading.
- Investigate authorization, proxy, and server policy when the response is an HTTP error.
- After each change, rerun the original case and compare the complete output. Record the working binary and environment so deployments use the same setup.
6. Avoid disabling certificate verification as a fix
Some builds expose options that ignore SSL errors. At most, use a verification bypass briefly in a controlled diagnostic to test whether certificate validation is the failing layer. Do not ship it as the remedy: it removes protection against untrusted or intercepted connections, and can expose rendered content or credentials to tampering.
Qt explicitly cautions: “Use QSslSocket::ignoreSslErrors() with caution as it will create security risks in your application.” See Qt’s SSL error documentation. If a temporary diagnostic changes the outcome, restore verification and fix the trust chain or CA configuration.
7. Common symptoms and fixes to investigate
| Symptom | Likely branch | Next check |
|---|---|---|
Warning: SSL error ignored |
Verification failure may be suppressed; the warning alone does not identify why. | Find the preceding error, identify the requested host, and check the certificate chain and trust store. |
QSslSocket: cannot resolve SSL_load_error_strings |
Qt/OpenSSL runtime symbol or library compatibility. | Identify the exact binary and loaded runtime libraries; compare them with the package’s build requirements. |
Failed loading page ... UnknownNetworkError |
Broad network failure; could involve the main document, a dependency, a redirect, or access policy. | Capture full logs and test each requested URL independently. |
| Only an image, stylesheet, font, or script is missing | Subresource host, redirect, trust, or access issue. | Test the exact asset URL and check its host, chain, response, and redirects. |
403 or “Forbidden” |
HTTP authorization or server/proxy policy. | Check credentials, cookies, proxy, IP rules, and redirects; do not infer a TLS handshake failure. |
| Works on a workstation but fails in a container | Different CA bundle, libraries, DNS, proxy, user permissions, or clock. | Run diagnostics inside the same container and as the same user as the renderer. |
8. Reliability, performance, and maintenance considerations
Rendering time can be spent waiting for the main document, redirects, or remote resources. A slow or unreachable dependency may delay or spoil the result even when TLS itself is working. Reduce unnecessary external dependencies, ensure assets are reachable from the renderer, and use deterministic local assets when the page does not need live remote content. Compare repeated runs with the same URL and environment before attributing intermittent behavior to TLS.
For repeatable production output, pin the renderer package and its runtime environment, keep the CA bundle current through the operating system’s normal mechanism, and log the binary version plus the failing URL and status. Because upstream is archived, evaluate any move to another renderer against your page requirements, deployment constraints, and security needs; the available research does not test or rank replacements.
Or skip the browser setup
If your goal is a website screenshot rather than maintaining a local wkhtmltoimage TLS stack, ScreenshotNeo provides a screenshot API and MCP server. One GET request returns an image or PDF. For example:
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, popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. An MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for free and get 1,000 screenshots a month with no card.
FAQ
Does “Warning: SSL error ignored” mean the page is safe to render?
No. It says an SSL error was ignored, not that the certificate was valid. Find the original validation error and fix the trust configuration.
Should I install a newer OpenSSL?
Only after confirming the binary’s runtime requirements and the library mismatch. Historical OpenSSL reports are clues, not a universal installation recipe.
Can a CDN cause the screenshot to fail?
Yes. A page may depend on a separate host for assets, and that request can fail while the main document is reachable. Test the precise resource URL and response.
Is a 403 an SSL handshake error?
Not by itself. A 403 is an HTTP response indicating that access was denied; investigate the server, proxy, and authorization path.


