October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Apple silicon

How to Fix wkhtmltopdf Errors in Laravel on macOS

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

Fix wkhtmltopdf failures in Laravel by isolating the failing layer in this order: run the exact binary from a macOS shell, point Snappy at that same executable, verify permissions and CPU architecture, repair Homebrew and runtime dependencies, then test fonts, URLs, JavaScript and local-file access. An exit status 126 is usually an executable or architecture problem, not a Blade or Laravel problem.

Start with the failure layer, not Laravel code

Laravel calls Snappy, and Snappy launches wkhtmltopdf as a separate process. A failure can therefore occur before Laravel renders a view, while the binary starts, while it loads libraries and fonts, or while it processes your HTML. The first useful question is whether the same executable can create a PDF outside PHP.

Symptom Likely layer First check
Shell says “cannot execute binary file” or Laravel reports exit status 126 Permission, wrong file type or CPU architecture ls -l, file, uname -m
Terminal works, Laravel fails Snappy points to another path or has a different environment Print the configured binary path and run that exact path manually
“No such file or directory” for an apparently present binary Bad path or missing runtime loader/library Confirm the path and inspect the file type and stderr
PDF is blank, missing images or has wrong fonts URL reachability, fontconfig/freetype or page timing Reduce the HTML to a tiny fixture and test assets separately
Local CSS/images are denied wkhtmltopdf local-file restrictions Use controlled URLs or a narrowly justified local-file option

1. Capture the exact error before changing anything

Save the complete Laravel exception and stderr, not just the final line. Record:

  • The complete command path Snappy attempted to run.
  • The full stderr output and numeric exit status.
  • PHP, Laravel and Snappy versions.
  • Your macOS version and whether the Mac is Intel or Apple Silicon.
  • A minimal HTML/CSS/JavaScript example that reproduces the failure.

The wkhtmltopdf project asks for the binary version, operating-system version, detailed description and a small test case when reporting an issue. Keeping this information also lets you distinguish a renderer defect from configuration, Homebrew or application markup.

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

2. Prove the binary works outside Laravel

Laravel Snappy’s README says that after installation you should be able to run wkhtmltopdf from the command line or shell. Do that with the exact file configured for your application.

  1. Locate the executable you intend to use. Use the path from your Snappy configuration, or inspect candidates with which wkhtmltopdf and your package manager.
  2. Ask it for its version and preserve both stdout and stderr:
    WKHTMLTOPDF='/path/to/wkhtmltopdf'; "$WKHTMLTOPDF" --version 2>&1
  3. Create a tiny fixture that does not depend on Laravel:
    printf '<!doctype html><html><body><h1>wkhtmltopdf test</h1></body></html>' > /tmp/wk-test.html
  4. Convert it directly:
    "$WKHTMLTOPDF" /tmp/wk-test.html /tmp/wk-test.pdf 2>/tmp/wkhtmltopdf.stderr; status=$?; cat /tmp/wkhtmltopdf.stderr; echo "exit=$status"; ls -l /tmp/wk-test.pdf

A successful shell conversion moves the investigation to Laravel’s path, environment or options. If this test fails, changing a Blade view will not repair the renderer; fix the executable or its dependencies first.

3. Point Snappy at the real macOS executable

Publish Snappy’s configuration and set binary to a file that actually exists on this Mac. Composer-installed binaries and system or Homebrew binaries are different installations; a Linux path copied from a deployment guide will not work on macOS.

  1. Publish the package configuration using the vendor-publish command documented by the Snappy package you installed. This creates config/snappy.php.
  2. Open that file and set the binary value to the absolute macOS path. For example:
    'binary' => env('WKHTMLTOPDF_BINARY', '/opt/homebrew/bin/wkhtmltopdf'),
  3. Put the same path in .env when you want machine-specific configuration:
    WKHTMLTOPDF_BINARY=/opt/homebrew/bin/wkhtmltopdf
  4. Clear cached Laravel configuration, then verify the resolved value. A stale config cache can make a corrected file appear to have no effect:
    php artisan config:clear
  5. Run the exact resolved path from step 2 again. Do not compare a successful interactive which wkhtmltopdf result with a different path in config/snappy.php.

In application code, keep PDF generation simple while diagnosing the executable:

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

use BarryvdhSnappyFacadesPdf;

$pdf = Pdf::loadView('invoice', ['invoice' => $invoice]);
return $pdf->download('invoice.pdf');

Remove custom options temporarily. Once a plain view converts, add options back one at a time so the first failing option is visible.

4. Fix exit status 126, permissions and CPU architecture

Status 126 means the shell found a file but could not execute it. Treat it as an executable or architecture problem before investigating HTML.

Check permissions

Inspect the mode and ownership:

ls -l /path/to/wkhtmltopdf

The file needs an execute bit for the user running PHP. If you control the file and it is otherwise trustworthy, add execute permission with chmod +x /path/to/wkhtmltopdf. Do not blindly change permissions on a package-managed location; correct the package installation or ownership instead.

Check that it is a macOS binary

file /path/to/wkhtmltopdf
uname -m

An Apple Silicon Mac normally reports arm64; an Intel Mac reports x86_64. Do not run a Linux amd64 executable on macOS. A documented M1 failure occurred because an x86_64 binary could not execute in that environment. Use a macOS build matching the host architecture, or deliberately provide the translation environment required by the particular build and verify it from the shell before involving Laravel.

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

Check for a path that is a script or broken link

ls -l "$(which wkhtmltopdf)"
file "$(which wkhtmltopdf)"

A symlink may lead to an uninstalled file, and a path copied from another machine may point into a nonexistent Composer directory. Resolve the link and configure the existing target.

5. Repair Homebrew and mixed Intel/Apple Silicon installations

Homebrew’s normal prefix is /opt/homebrew on Apple Silicon and /usr/local on Intel. A Mac upgraded over time can contain both trees, leaving your interactive shell, PHP process and Snappy with different tools.

  1. Check which Homebrew and renderer are being used:
    which brew
    brew --prefix
    which wkhtmltopdf
    brew --prefix wkhtmltopdf
  2. Compare the result with your Mac architecture:
    uname -m
  3. Refresh package metadata and inspect diagnostics:
    brew update
    brew doctor
  4. Read every warning from brew doctor, especially stale Command Line Tools after a macOS upgrade and PATH entries that mix /usr/local with /opt/homebrew.
  5. Retry the original direct conversion while preserving complete output.

Do not assume that fixing your shell’s PATH fixes PHP-FPM, a queue worker or a web-server process. An absolute binary path in Snappy is more reproducible than relying on an inherited PATH.

6. Check libraries, fonts and rendering inputs

wkhtmltopdf builds depend on platform runtime libraries and on fontconfig and freetype configuration. Laravel Snappy documentation also notes that dependencies such as libXrender may require manual installation, depending on the build. Use the dependency instructions for the exact macOS package you installed; do not copy Linux package commands into Homebrew.

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

Use a staged rendering test

  1. Convert plain text and a system font with no CSS or images.
  2. Add a local stylesheet.
  3. Add one image using an absolute, reachable URL.
  4. Add web fonts only after ordinary text renders correctly.
  5. Finally add JavaScript and remote assets.

This identifies whether the failure is process startup, font discovery, a blocked URL or page timing. Confirm fonts are installed for the account that runs the PHP process; a font visible in your desktop session may not be visible to a queue worker.

The stable wkhtmltopdf series identified by the project is 0.12.6, released June 11, 2020. Treat the version printed by your installed executable as authoritative, because package provenance and build options affect available behavior.

7. Handle local files without weakening security

Modern wkhtmltopdf behavior can block local-file access. Prefer serving CSS, images and other assets through controlled URLs that the renderer can reach. If a trusted, sanitized document genuinely requires local files, enable access narrowly and test the smallest directory needed.

KnpLabs’ Snappy README warns that “The --enable-local-file-access option in wkhtmltopdf can be risky if used with untrusted HTML or JavaScript.” The wkhtmltopdf project likewise warns not to use it with untrusted HTML. Never pass user-supplied markup, JavaScript or arbitrary file paths to a process that can read local files. Keep authorization, path validation and input sanitization outside the renderer.

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

8. Make Laravel’s execution environment match your shell

When Terminal succeeds but a controller, queue or scheduler fails, compare environments rather than reinstalling Laravel.

  • Log the absolute Snappy binary path at runtime (without exposing secrets).
  • Run the same PHP user and working directory used by the failing process where practical.
  • Confirm that the process can read the Blade view, temporary directory, fonts and any asset URLs.
  • Use an absolute binary path instead of assuming the web server inherited your interactive shell PATH.
  • Clear Laravel’s configuration cache after changing config/snappy.php or .env.

For queue workers, restart the worker after configuration changes. A long-running worker can retain old configuration even after the files are corrected.

9. Diagnose HTML, CSS and JavaScript after startup works

Once the tiny shell fixture succeeds, reduce your application document until it succeeds too. Remove scripts, remote stylesheets, web fonts and large images, then restore each category separately. Check that every URL is reachable from the Mac, that redirects do not require an interactive login, and that generated asset URLs use the correct scheme and host.

If content appears only after JavaScript runs, use the Snappy option that waits for the required condition, such as a selector or a deliberate delay, and keep the wait no longer than necessary. A renderer timeout can otherwise look like a Laravel failure. Capture stderr for warnings about blocked resources, TLS or malformed markup.

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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

10. Build a reproducible local and deployment setup

Document the binary provenance, version, architecture, absolute path, required libraries and fonts, and the exact command that converts your minimal fixture. Keep that fixture in the project’s diagnostic notes or test suite. On each development or deployment machine, verify:

  • uname -m matches the renderer build you selected.
  • The configured absolute path exists and is executable.
  • The binary prints its version without an error.
  • The minimal HTML conversion creates a non-empty PDF.
  • The PHP process can read required templates and assets.

This prevents a Composer update, Homebrew migration or macOS upgrade from silently switching the executable underneath Laravel.

Common errors and precise fixes

Error or symptom Cause to test Fix
Exit status 126 Non-executable file, wrong binary format or architecture mismatch Run ls -l, file and uname -m; install a macOS build and correct execute permission
Exit status 127 or “command not found” Snappy path is wrong or target was removed Find the existing executable and set its absolute path in config/snappy.php; clear config cache
Terminal succeeds, Laravel fails Different path, PATH, user, permissions or working directory Run the exact configured path as the PHP process and log the resolved configuration
Missing library or loader message Incomplete package or stale developer tools Run brew update and brew doctor; follow the build’s dependency instructions
Blank PDF or missing glyphs Fontconfig/freetype, unavailable fonts or renderer timing Test a plain document, install/verify fonts for the service user, then add assets incrementally
Images or CSS missing Unreachable URL, blocked local file or authentication requirement Use controlled reachable URLs, validate permissions and avoid broad local-file access
Works on Intel but not M1/M2 x86_64 versus arm64 binary or mixed Homebrew prefixes Match the build to the host, inspect both Homebrew prefixes and remove ambiguous PATH entries

11. Escalate with a minimal reproduction

If the direct fixture still fails after permissions, architecture, Homebrew and dependencies are correct, submit a focused report. Include the binary’s --version output, macOS version, uname -m result, exact command, complete stderr and the smallest HTML/CSS/JavaScript file that fails. State whether the failure occurs in a shell, a web request, a queue worker or all three. This gives maintainers enough information to separate a renderer defect from Laravel configuration, package installation or application markup.

Or skip the browser setup

If your goal is a clean screenshot or PDF of a web page rather than a wkhtmltopdf-specific Laravel pipeline, ScreenshotNeo makes the capture a single API request. It accepts the consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before the capture; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

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

cURL:

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 all options, including full-page capture, element selectors, device and viewport settings, retina scale, PDF paper and margin controls, custom CSS and JavaScript, click and wait actions, request blocking, headers, cookies, user agent, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture and usage reporting.

Python:

import requests
r = requests.get('https://api.screenshotneo.com/v1/shot', params={'access_key': 'YOUR_API_KEY', 'url': 'https://stripe.com'}, timeout=90)
r.raise_for_status()
open('shot.webp', 'wb').write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 screenshots, and every feature is included on every plan. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can ScreenshotNeo reproduce a PDF generated by my Laravel view?

It captures a publicly reachable URL, not a PHP view that exists only inside your application process. Deploy or expose the page through an authenticated, controlled URL first, then use the capture options or capture_pdf tool.

Should I switch from wkhtmltopdf solely because it is old?

No. First establish whether your current 0.12.6-based build works for your document and security requirements. Replace it when you need a maintained rendering stack, a different CSS/JavaScript capability or a deployment model your current binary cannot support.

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

What is the safest way to test a local-file workaround?

Use a sanitized fixture containing only files from a dedicated directory, run it under the same service account as Laravel, and remove the local-file option after confirming that controlled URLs can serve the required assets.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.