If wkhtmltoimage appears to fail when PHP runs it, first stop relying on shell_exec()’s return value as a success signal: it does not provide the child process’s exit status, and a null result can mean either an error or no output. Use exec() to capture the exit code and diagnostics, then test the exact executable, arguments, and output path as the PHP service account. That separates PHP process-launch problems from renderer, permissions, and runtime problems.
Why shell_exec() is a poor failure detector
shell_exec() runs a command through the shell and returns its output as a string. It does not expose the command’s exit status. PHP’s manual also notes that its return value can be null when an error occurs or when the command produces no output, so an empty-looking result alone does not tell you whether wkhtmltoimage succeeded. PHP recommends exec() when you need the program’s exit code: PHP shell_exec() manual.
There are two distinct things to diagnose: whether PHP could start the process, and whether the renderer completed the requested capture. A reliable check records the child status, standard output, and standard error, and then verifies that the expected output file exists and is usable.
Capture the exit code and error output
For a short diagnostic, use exec() and temporarily redirect standard error into standard output. Escape each argument rather than concatenating untrusted values into a shell command. This example assumes you have already set the executable path and output directory to locations appropriate for your server:
#1 Best Overall
<?php
$binary = '/usr/local/bin/wkhtmltoimage';
$url = 'https://example.com';
$output = '/var/www/app/storage/example.png';
$command = escapeshellarg($binary)
. ' --format png '
. escapeshellarg($url)
. ' '
. escapeshellarg($output)
. ' 2>&1';
$lines = [];
$exitCode = null;
exec($command, $lines, $exitCode);
error_log('wkhtmltoimage exit code: ' . $exitCode);
error_log('wkhtmltoimage output: ' . implode("n", $lines));
if ($exitCode !== 0 || !is_file($output) || filesize($output) === 0) {
http_response_code(500);
echo 'Screenshot generation failed.';
exit;
}
echo 'Screenshot created.';
?>
Replace the illustrative paths and URL with your actual values. Keep the diagnostic output in server logs, not in a response shown to arbitrary visitors: error text can expose filesystem paths, command details, or other sensitive information. Once you have diagnosed the problem, handle errors in your application’s normal logging and response flow.
What the result tells you
- A nonzero exit code means the renderer command did not complete successfully; inspect the captured diagnostic text.
- A zero exit code with no output file, or a zero-byte file, means the command’s status alone was not enough to verify the expected result. Check the destination path and the renderer output.
- A failure before the renderer starts can point to an invalid executable path, insufficient execute/traverse permissions, or a PHP process policy that blocks execution.
For production code, a process library can provide structured error handling and a configurable executable path. The phpwkhtmltopdf documentation describes configuring the full binary path and retrieving detailed errors. Its default assumes the command can be found through the shell’s search path, which may not match the environment used by a PHP service.
Check the executable path and PHP service account
A command that works in your terminal is not necessarily running in the same environment as a web request. PHP may run under a different account, with a different PATH, filesystem access, service policy, or working directory. Treat those differences as things to verify rather than assuming any one is the cause.
Rank #2
- Record the PHP execution context: operating system and version, PHP version, and whether the request runs through a web server, PHP-FPM, a container, or another service.
- Find the executable path used by the deployment. Configure that absolute path in the command or wrapper rather than depending on an interactive shell’s
PATH. - Check that the PHP service account can execute the binary and traverse every parent directory in its path.
- Check that the same account can write to the destination directory and replace or create the target file.
- Run a minimal test as that same account, outside the web request, using the same binary, arguments, and output location.
Do not respond to a permission error by making the binary or output directory world-writable with permissions such as 777. Grant only the access the service needs, and check whether a mount option or service security policy prevents execution.
Verify runtime compatibility, libraries, and fonts
The executable must match the deployment environment. The wkhtmltopdf project’s downloads page identifies 0.12.6 as its stable series and gives June 11, 2020 as the release date; that is a dated project statement, not confirmation that this is the latest or a currently supported choice for every system. The same page warns that generic binaries generally do not work on Alpine Linux because Alpine uses musl rather than glibc, and points users toward distribution-specific packages where available: wkhtmltopdf downloads.
If the process starts but fails while loading the renderer, check whether the binary and its required runtime libraries are present and compatible with the host. Packaged or serverless deployments may also need their runtime libraries and font configuration included. Missing fonts more commonly affect rendering appearance than process launch, so distinguish a process error from a capture that completes but looks wrong.
- Use a package intended for the target distribution where possible; do not assume a downloaded binary is portable across Linux distributions.
- In a container or serverless package, confirm the deployed artifact includes required libraries and font configuration, not just the executable.
- If the renderer works on one host but not another, compare the OS, architecture, library environment, and installed fonts before changing PHP code.
If you use PHP’s wkhtmltox extension rather than launching the standalone wkhtmltoimage program, the PHP requirements page has a separate Windows note: add wkhtmltox.dll to PATH. That extension requirement should not be confused with the standalone executable’s path: PHP wkhtmltox requirements.
Reproduce the failure outside the web request
A small controlled test helps isolate whether the failure is in the PHP call, the deployment environment, or the page being rendered. Use a local HTML file first, then test the target URL. Keep the account, binary, and destination consistent with the web service.
Recommended Free Tools
- Create a simple HTML file with plain text and no external CSS, scripts, fonts, or images.
- Invoke the absolute-path binary as the PHP service account, using a writable output path and capturing its exit status and standard error.
- Confirm the output file is created and nonempty; open it or inspect its image metadata.
- If the local file works, try the target URL. If that fails, investigate network access, redirects, page load behavior, and references to local or remote resources.
- Change one variable at a time: executable path, permissions, output location, libraries, fonts, then input page or resource access.
This is a diagnostic sequence, not a universal fix: the appropriate correction depends on which condition fails in your deployment.
Rank #4
Keep HTML rendering inside a security boundary
Rendering user-controlled HTML or JavaScript is not merely a reliability issue. The wkhtmltopdf project warns against using wkhtmltopdf with untrusted HTML unless user-supplied content is sanitized, because it can lead to complete server takeover. Treat that warning as relevant whenever users can influence the rendered markup or resources.
Sanitize untrusted input and constrain the renderer’s operating-system access. The project’s AppArmor guidance describes confinement of filesystem and command access on supported Linux systems. It also explains why the renderer’s --disable-local-file-access option alone may not be a sufficient boundary in the presence of a binary vulnerability. Do not “fix” a blocked resource or command by granting unrestricted access to the server.
Common failure symptoms and fixes
| Symptom | What to check | Next step |
|---|---|---|
shell_exec() returns null or appears blank |
The function does not reveal the child exit status, and null is ambiguous. |
Use exec() or a process wrapper to capture status and diagnostics; verify the output file. |
| “Command not found” or no executable starts | The PHP service’s PATH may differ, or the configured path may be wrong. |
Use and verify the absolute binary path under the PHP service account. |
| “Permission denied” | Execute permission, parent-directory traversal, destination write access, mount options, or service policy. | Grant the minimum required access and retest as the service account; avoid blanket chmod 777. |
| Works on another Linux distribution but not Alpine | Generic binaries generally do not work in Alpine’s musl environment. | Use a compatible, distribution-specific package or deployment build. |
| Process starts but reports missing libraries or fails in a packaged runtime | Required libraries or runtime configuration may not be included. | Include compatible runtime dependencies and font configuration in the deployed environment. |
| Image is missing content or has unexpected appearance | Input resources, fonts, or page behavior may differ from the simple local test. | Compare local-file and URL captures, then test resource access and fonts separately. |
What to include in a support request
If you still cannot isolate the cause, provide enough detail for someone else to reproduce it. The wkhtmltopdf project’s support page asks for the renderer version, operating system and version, and a detailed reproducible case: wkhtmltopdf reporting issues.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems- Renderer version; operating system and version; PHP version and execution context.
- Exact executable path and command options, with secrets removed.
- Exit code and captured standard error.
- A minimal reproducible HTML, CSS, and JavaScript case, plus any relevant resource-loading details.
- The output path and whether the service account can write there.
Or skip the browser setup
If your actual goal is to obtain a website screenshot rather than to repair a PHP installation of wkhtmltoimage, ScreenshotNeo offers a screenshot API and MCP server. It does not fix a broken local renderer; it is an alternative capture route. A single GET request can return an image or PDF. For example, using the documented cURL pattern with the target URL changed to your page:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies page verdict and billing status in headers. An MCP server lets AI agents—including Claude, Cursor, and other MCP clients—take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for the free plan.
Frequently Asked Questions
Does an empty string from shell_exec() prove wkhtmltoimage succeeded?
No. Output content and process success are different signals; check the exit status and expected output file.
Should I use wkhtmltopdf or wkhtmltoimage to make an image?
Use the executable that matches the output you need; the troubleshooting here concerns launching the image renderer from PHP.
Outdated 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 matchPC 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 & 11Quick 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.

