Self-hosted pdf generation not working

Version ie <v5.10.30>

Environment <Docker/Shared Hosting/Zip/Other>

Checklist

  • Can you replicate the issue on our v5 demo site https://demo.invoiceninja.com or Invoice Ninja? NO
  • Have you searched existing issues? YES
  • Have you inspected the logs in storage/logs/laravel.log for any errors? YES

Describe the bug

I am trying to get the PDF rendering to work on localhost, I have generated a fake domain “invoiceninja.test” and am pointing it to my ip in the drivers/hosts file on my pc, which is working to access invoice ninja via the browser, however there is still no pdf, I then saw a commented line in the .env file “#SNAPPDF_CHROMIUM_PATH=/usr/bin/google-chrome-stable” which I uncommented and then the docker won’t build or start and says the following : app-1 | /bin/sh: 0: Illegal option -. I would like some assistance to get this working as I cannot seem to do it.

Steps To Reproduce

Run a fresh install of invoiceninja docker, uncomment the following line in the .env
#SNAPPDF_CHROMIUM_PATH=/usr/bin/google-chrome-stable

Expected Behavior

PDFs to be generated

Additional context

I have also had a look at the console logs in the browser when I click to view the pdf and they are as follows.

bundle.Dp8oIWDU.js:145

   GET http://invoiceninja.test/client/invoice/tVInUILJNpw0B5RhQmByn7RJrji409Lq/download_pdf 500 (Internal Server Error)

(anonymous) @ bundle.Dp8oIWDU.js:145
xhr @ bundle.Dp8oIWDU.js:145
tAe @ bundle.Dp8oIWDU.js:147
_request @ bundle.Dp8oIWDU.js:148
request @ bundle.Dp8oIWDU.js:147
(anonymous) @ bundle.Dp8oIWDU.js:143
Qe @ bundle.Dp8oIWDU.js:419
queryFn @ InvoiceViewer-DSDa_EFe.js:1
p @ bundle.Dp8oIWDU.js:395
f @ bundle.Dp8oIWDU.js:395
VWe @ bundle.Dp8oIWDU.js:395
e.fetch @ bundle.Dp8oIWDU.js:395
e.fetchQuery @ bundle.Dp8oIWDU.js:395
(anonymous) @ InvoiceViewer-DSDa_EFe.js:1
yT @ bundle.Dp8oIWDU.js:57
Rx @ bundle.Dp8oIWDU.js:57
(anonymous) @ bundle.Dp8oIWDU.js:57
E @ bundle.Dp8oIWDU.js:42
B @ bundle.Dp8oIWDU.js:42
bundle.Dp8oIWDU.js:419 Qs {message: ‘Request failed with status code 500’, name: ‘AxiosError’, code: ‘ERR_BAD_RESPONSE’, config: {…}, request: XMLHttpRequest, …}code: "ERR_BAD_RESPONSE"config: {transitional: {…}, adapter: Array(3), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Request failed with status code 500"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}response: {data: ArrayBuffer(131), status: 500, statusText: ‘Internal Server Error’, headers: np, config: {…}, …}status: 500stack: “AxiosError: Request failed with status code 500\n at IVe (http://invoiceninja.test/bundle.Dp8oIWDU.js:145:1045)\n at XMLHttpRequest.v (http://invoiceninja.test/bundle.Dp8oIWDU.js:145:5723)\n at QI.request (http://invoiceninja.test/bundle.Dp8oIWDU.js:147:2085)”[[Prototype]]: Error
(anonymous) @ bundle.Dp8oIWDU.js:419
Promise.then
_request @ bundle.Dp8oIWDU.js:148
request @ bundle.Dp8oIWDU.js:147
(anonymous) @ bundle.Dp8oIWDU.js:143
Qe @ bundle.Dp8oIWDU.js:419
queryFn @ InvoiceViewer-DSDa_EFe.js:1
p @ bundle.Dp8oIWDU.js:395
f @ bundle.Dp8oIWDU.js:395
VWe @ bundle.Dp8oIWDU.js:395
e.fetch @ bundle.Dp8oIWDU.js:395
e.fetchQuery @ bundle.Dp8oIWDU.js:395
(anonymous) @ InvoiceViewer-DSDa_EFe.js:1
yT @ bundle.Dp8oIWDU.js:57
Rx @ bundle.Dp8oIWDU.js:57
(anonymous) @ bundle.Dp8oIWDU.js:57
E @ bundle.Dp8oIWDU.js:42
B @ bundle.Dp8oIWDU.js:42
Np7BB03RjKPrfLhxe1itWeXJggWDWN8fcr5dkLBa.png:1

   GET http://192.168.0.248:8012/storage/z1s6SWkehhlvensSfdCdmoGAy8thGXjP/Np7BB03RjKPrfLhxe1itWeXJggWDWN8fcr5dkLBa.png net::ERR_CONNECTION_REFUSED

Screenshots

Logs

#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Http\FlushEventsMiddleware->handle()
#41 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(45): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Http\SetRequestIpMiddleware->handle()
#43 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(31): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Http\SetRequestMiddleware->handle()
#45 /var/www/html/vendor/livewire/livewire/src/Features/SupportDisablingBackButtonCache/DisableBackButtonCacheMiddleware.php(19): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Livewire\Features\SupportDisablingBackButtonCache\DisableBackButtonCacheMiddleware->handle()
#47 /var/www/html/app/Http/Middleware/Cors.php(24): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): App\Http\Middleware\Cors->handle()
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Http\Middleware\TrustProxies->handle()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#52 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#53 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle()
#54 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#55 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#56 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#57 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#58 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Http\Middleware\ValidatePostSize->handle()
#59 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#60 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#61 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php(79): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#62 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Tracing\Middleware->handle()
#63 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#64 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\Pipeline\Pipeline->then()
#65 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#66 /var/www/html/public/index.php(56): Illuminate\Foundation\Http\Kernel->handle()
#67 {main}
“}
[2025-04-02 14:09:29] production.ERROR: Unable to generate the raw PDF => Browser binary not found. Make sure you download it or set using setChromiumPath(). {“userId”:1,“exception”:”[object] (App\Exceptions\FilePermissionsFailure(code: 0): Unable to generate the raw PDF => Browser binary not found. Make sure you download it or set using setChromiumPath(). at /var/www/html/app/Jobs/Entity/CreateRawPdf.php:148)
[stacktrace]
#0 /var/www/html/app/Jobs/Entity/CreateRawPdf.php(103): App\Jobs\Entity\CreateRawPdf->generatePdf()
#1 /var/www/html/app/Http/Controllers/InvoiceController.php(866): App\Jobs\Entity\CreateRawPdf->handle()
#2 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\Http\Controllers\InvoiceController->downloadPdf()
#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\Routing\Controller->callAction()
#4 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php(21): Illuminate\Routing\ControllerDispatcher->dispatch()
#5 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php(18): Sentry\Laravel\Tracing\Routing\TracingControllerDispatcherTracing->Sentry\Laravel\Tracing\Routing\{closure}()
#6 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php(20): Sentry\Laravel\Tracing\Routing\TracingRoutingDispatcher->wrapRouteDispatch()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(266): Sentry\Laravel\Tracing\Routing\TracingControllerDispatcherTracing->dispatch()
#8 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\Routing\Route->runController()
#9 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\Routing\Route->run()
#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#11 /var/www/html/app/Http/Middleware/QueryLogging.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): App\Http\Middleware\QueryLogging->handle()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(51): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Routing\Middleware\SubstituteBindings->handle()
#15 /var/www/html/app/Http/Middleware/TokenAuth.php(102): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#16 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): App\Http\Middleware\TokenAuth->handle()
#17 /var/www/html/app/Http/Middleware/SetInviteDb.php(81): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): App\Http\Middleware\SetInviteDb->handle()
#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle()
#21 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#23 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#25 /var/www/html/app/Http/Middleware/SessionDomains.php(30): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): App\Http\Middleware\SessionDomains->handle()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#29 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Session\Middleware\StartSession->handle()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\Pipeline\Pipeline->then()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\Routing\Router->runRouteWithinStack()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\Routing\Router->runRoute()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\Routing\Router->dispatchToRoute()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\Routing\Router->dispatch()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(170): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()
#39 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/FlushEventsMiddleware.php(13): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Http\FlushEventsMiddleware->handle()
#41 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(45): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#42 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Http\SetRequestIpMiddleware->handle()
#43 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(31): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#44 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Http\SetRequestMiddleware->handle()
#45 /var/www/html/vendor/livewire/livewire/src/Features/SupportDisablingBackButtonCache/DisableBackButtonCacheMiddleware.php(19): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Livewire\Features\SupportDisablingBackButtonCache\DisableBackButtonCacheMiddleware->handle()
#47 /var/www/html/app/Http/Middleware/Cors.php(24): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): App\Http\Middleware\Cors->handle()
#49 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#50 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Http\Middleware\TrustProxies->handle()
#51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#52 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#53 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle()
#54 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#55 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#56 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#57 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#58 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Http\Middleware\ValidatePostSize->handle()
#59 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#60 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#61 /var/www/html/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php(79): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#62 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(209): Sentry\Laravel\Tracing\Middleware->handle()
#63 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(127): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#64 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\Pipeline\Pipeline->then()
#65 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#66 /var/www/html/public/index.php(56): Illuminate\Foundation\Http\Kernel->handle()
#67 {main}
"}

Hi,

Have you tried using the hosted_ninja renderer, it’s easier to get working than SnapPDF.

No I have not, is there a guide on how to do that?

You need to change the value in the .env file

1 Like

That has worked, thank you!!

Are there limits to this, ie. amount if requests etc.

As long as your usage is within reason you shouldn’t run into any limits, the limits are more to prevent abuse.

Thank you for your help, I truly appreciate it!!

Of course, happy to help!