Wkhtmltopdf rendering without CSS - custom and core - all standard solutions have no affect - ubuntu 18.04

Fonts load fine weirdly enough, but the CSS (grid/alignment) formatting is stripped out and the print is resized to ~65% of what it should be.



(plus a few others)

  • did the libssl1 install, then updated wkhtmltopdf to the latest version 0.12.5
  • added “http_port”: 443 to my site_config
  • reset server hostname via hostnamectl {sitename}
  • tried with all firewalls down
  • ran ‘bench use’ and ‘bench setup nginx’ as well as ‘use-url https’, etc
  • half a dozen other things mentioned in various other fixes; then reset, and cleanly did just the basics listed above again.

I got nothing. Still doing this with custom print formats as well as core- both saving to pdf as well as trying to actually print.

The ability to print invoices is kind of super business-critical if anyone has any suggestions, they would be greatly appreciated.

**Edit- screenshots of ‘print preview’, ‘save pdf’, and ‘print[to actual printer]’ using a test invoice/customer and the ‘example’ print format unchanged and without any CSS–

*note: I have the pdf.py margins set to ~1mm, the edge to edge is normal and not part of the issue.

I was having all kinds of issues getting custom print formats to work properly. Sometimes it would print correctly but not be in emailed versions of the same docs. Other times it just would not reliably configure the page at all.

Not sure if this will work for you, but once I did it to all of my servers, the problems went away.

See this post:

Evidently, wkhtmltopdf needs to be able to find your server by it’s assigned server name in order to operate properly and reliably. Just change ‘localhost:8000’ to whatever your URL for your server happens to be.

Hope this helps…


Thanks for the response! the
… site_config hostname…
command is either deprecated or not valid for existing multitenant/ssl configurations. I’m assuming the former rather than the latter.

Regardless, it seems like the command itself added the defined hostname to the site_config. seeing as the entry I had in there was for “host_name”: “site”, I went ahead and added a second one for “hostname”: “site”, just in case. No effect.

However- some further information on it. It is DEFINITELY an ssl/https issue, as setting up a basic test.html with a callout to an https website image and running directly from cli results in an empty image box.

With that in mind, I ran it on cli on the same test.html with ‘–ssl-crt-path’ and the lets-encrypt ssl path from site_config, no effect.

Hi probably this is the command option BKM refers to -

frappe@ubuntu1804lts:~/frappe-bench$ bench set-url-root --help
Usage: bench set-url-root [OPTIONS] SITE URL_ROOT

  Set url root for site

  --help  Show this message and exit.

Not likely. I have done this on both v10 and v11 servers. So the command may just need to be edited to replace ‘site1.local’ with the site name you assigned to your tenant and replace ‘localhost:8000’ with the URL you assigned to the same tenant.

Do this for each tenant on the server.

I have done this on v10 and v11 systems. Not tested on v12


@clarkej Thanks, I must have skimmed past that part…

  • bench set-url-root https:// had no effect.
  • bench set-url-root had no effect.
    Am I using the correct syntax? It is just the site url, correct, not something like – or “”? I received no errors and the site was still accessible after both variations, and a quick google/docs search for syntax didn’t show me anything.

@bkm I’m on a hosted vps (digitalocean) with an ssl-configured site on a custom domain. well, subdomain, but same difference. the current live site was installed on 18.04 via easy install with my site preconfigured instead of any version of a site1.local via the py.install --{site} --{db pw} --{admin password} etc args and has never been accessed locally or even available on port 8000, as ufw was configured during initial install to block all except 22, 80, 443. I only mention all of this because while there is definitely some issue with some ssl config/package somewhere, the only issue I’m having because of it is wkhtmltopdf not being able to pull css- I could be wrong here, but I’m fairly sure that the solutions you are suggesting seem like they would be demonstrating far greater connectivity issues than just css pulling and are more tuned towards converting local sites > live sites.

As far as continuing research into the ssl issue- per:

I started looking into the installed ssl packages, as ‘apt-get install libssl1.0-dev’ seems to fix ssl for most, but was already installed. I am on nodejs 10.15, so installed openssl1.1 (no effect on printing after nginx reset/clear-cache/supervisorctl restart). However, just to see what it said, I tried apt-get install libssl1.0-dev again and now am receiving:

*note- due to previous experience, I was attempting installs on variants of …-dev in the screenshot, but it’s the same responses/principle with the straight …libssl1.0-dev’ command.

Is there a better way to trace the various paths/connections/calls in order to get a better idea of what is happening?

TBH I can’t say if these two are equivalent so you may have to experiment:

bench set-url-root mysite.com https://mysite.com
bench set-config host_name https://mysite.com

They generally affect this key: value pair

“host_name”: “https://mysite.com”,

here in this file:


As well these you need to set for example this too:

bench set-ssl-key mysite.com /etc/nginx/ssl/nginx.key
bench set-ssl-certificate mysite.com /etc/nginx/ssl/nginx.crt

If you edit site_config.json be sure to observe the json syntax with commas and so on.

I found this that may help with your learning SSL Configuration for HTTPS

Your Digital Ocean host is well documented - for example you may need to specify mysite.com in /etc/hosts? A creative search here say ‘Digital Ocean hosts ssl’ may give you clues.


It seems you have missed the point of my directing you to the solution post.

Your problem has nothing to do with port 8000 or anything else like that.

Your problem has to do with wkhtmltopdf NOT paying attention to normal internal hosting conventions.

The solution post I pointed you toward was an example of a similar but different situation related to a self hosted instance on a local box, but the concept is identical.

The wkhtmltopdf package is looking for higher level hostnames in order to process and pass information.

YES, it does appear to sometimes work intermittently without any specific hostname identified, but that has more to do with information left in the browser buffers at the time of the request and NOT the actual internal workings of wkhtmltopdf.

You don’t have to believe me. But you should try it with the correct syntax before you poo poo it.

Also remember once you have added the corrections to the site_config.json you must also do:

bench setup nginx
sudo service nginx restart

All of my existing systems are hosted on various VPS providers. All of them are multitenant configured even if some only have one tenant. All of them are running lets encrypt certificates.

And all of them had some level of the same problem until I used the solution I pointed you toward.

Here is an example of one command I ran on one of my stores VPS servers:

bench --site jmistore.com set-config hostname “https://erp.jmistore.com
bench setup nginx
sudo service nginx restart

(note: jmistore.com if a fake address and is only used here for demonstration purposes)

Again, you seem to have misread the intent of the solution. It was just an example of syntax. Once you build the correct syntax for your server situation and follow the rest of the nginx steps, you should have solved you problems as well. The wkhtmltopdf package will them be able to collect the css information, the custom format, letterhead, and data before building the PDF file. Everything here is related to the wkhtmltopdf package NOT playing by the same set of rules as the rest of ERPNext so you have to make sure you tell it where to find things in a language it understands. It only seems to understand hostnames internal to itself. (only tested on v10 and v11)


1 Like

Here is yet another example of someone that was overthinking the problem until they tried this simple solution:


It should be … set-config hostname

NOT …site_config hostname


1 Like

Yeah, the set_config vs set-config was definitely why the command wasn’t running, worked that bit out last night, lol.

At this point, I have done a ground up reinstall and restore with site-config, nginx, lets-encrypt, and the rest all redone.

Still having the issue.

Having installed the nodejs 8.x package this go-around to avoid any possible conflicts with nodejs 10.x and it’s openssl interfering with libssl1.0-dev, libssl1.0-dev is cleanly installed with no mention of ‘holding bad packages’ or whatever from the system. So… wkhtmltopdf (upgraded to 0.12.5 (patched qt support)) should be happy.

Still having the issue.

Added the site hostname, both as a bare hostname and as https://:443 to /etc/hosts and changed /etc/hostname to the site.

Still having the issue.

AT THIS POINT, I see what happens if I try to connect directly to the ip, and get an SSL certificate error due to the certificate being set for the hostname rather than the ip… makes sense, but also makes me think about something else I set up about a week ago- a floating point ip configuration on digitalocean so that I could set dns to the floating point and swap in and out different vps’s for testing purposes. Looking at the digitalocean docs, they explicitly mention that while this will work fine in any situation for most services, for a production web server, lets-encrypt would only function properly through them on domains they hosted.

SO, I’ve nixed the floating point and changed Google Domains dns a record from the floating point to the static ip of the actual vps. No effect so far, but I’ll give it an hour or 2 for the dns change to fully propagate. Will keep you guys advised. Thanks for all of the assistance thus far!

Okay. So yeah. I’ve killed ip6 with fire, same with the floating point ip.

running from cli pulls the test.html (without image from https source) and https://www.google.com (without css/‘prettifying’… but with color?) as it has since the beginning. interestingly, it does it without any type of error flag.

I can’t find a debug method to watch exactly it is doing in order to try and figure out what is going wrong – if someone knows a log location or debug arg/method, please let me know.

At this point, I’m just going to have to give up for now and try and write a simple-as-possible invoice template based on absolute position placement.

What I can’t figure out is- it pulls the font and font-size info, just not the columns/grid info. The font/size info is in the css, not the html proper. So why… Why… doesn’t it take the column/grid info?

Still can’t get it to load the grid, but more and more I’m thinking that’s a css issue {the ‘core’ example html had no css with it nor did I define any, and my template is… well… a hackjob at best).

The ‘test.html’ I had been working with to run wkhtmltopdf from cli was grabbed from a post on here that had talked about using it for the same purpose, but after looking at it, I realized the https img src was the erp logo svg on wikipedia… I don’t know if I’m supposed to have svg support through wkhtmltopdf, but once I changed the img source to a https-based png, it ran fine. running it on the entire https page including the img (my erp products site) spat out a picture perfect pdf with site/picture/everything.

So yeah. At some point through all of this, it seems like the issue is no longer wkhtml-related… and, in fact, if I’m being honest, I feel like there was a point this morning where I looked at pdf export # 681,379 and thought, “do… do those letters look cleaner? naah… even if they do, the alignment is still messed up.”

I’d be willing to bet that was somewhere around getting libssl1.0-dev squared, wkhtml update squared, and 'bench --site set-config hostname “https://”

Thanks, @bkm, @clarkej, @vrms

*sidenote- I would definitely keep an eye on the whole nodejs 10.x/openssl1.1 thing and how it conflicts with libssl1.x- the biggest reason I opted to just rebuild was that I was getting all kinds of things like the screenshot above and I wanted to go ahead and start fresh with nodejs 8.x.

I had the same issue due to the command being with underscore instead of dash in one of the reference Topics. I have learned however that it’s often worth to look at bench --help if something does not work. This has taught me bench set-config is the actual spelling.

1 Like