Skip to main content

Odoo PDF Report Renders Blank Page — How to Fix It Fast

Odoo PDF report comes out blank in 17/18/19? Diagnose wkhtmltopdf, QWeb template, and report action with full troubleshooting steps in production today.

E
ECOSIRE Research and Development Team
|May 4, 20267 min read1.2k Words|

A user prints an Odoo report. The PDF downloads. The PDF is one blank page (sometimes more). The HTML preview in the browser looks fine — content visible, formatting correct. Only the PDF is empty. The server log shows a clean run:

A user prints an Odoo report. The PDF downloads. The PDF is one blank page (sometimes more). The HTML preview in the browser looks fine — content visible, formatting correct. Only the PDF is empty. The server log shows a clean run:

INFO: Generated report sale.report_saleorder for record sale.order(14,)

This is a class of Odoo report bugs where the QWeb template, the report action, and wkhtmltopdf interact in subtle ways. Applies to Odoo 17.0/18.0/19.0.

Quick Fix

Test with HTML output to isolate. Add &report_type=qweb-html to the report URL:

/report/pdf/sale.report_saleorder/14    → blank PDF
/report/html/sale.report_saleorder/14   → HTML, also blank?

If HTML is blank too, the QWeb template is wrong. If HTML is fine but PDF is blank, wkhtmltopdf is the problem.

For the wkhtmltopdf case, ensure the binary version is correct (Odoo 17.0/18.0/19.0 require wkhtmltopdf 0.12.6 with patched Qt):

wkhtmltopdf --version
# wkhtmltopdf 0.12.6 (with patched qt)

# If wrong, install the right one:
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
sudo dpkg -i wkhtmltox_0.12.6.1-3.jammy_amd64.deb

Why This Happens

Odoo PDF reports go: QWeb template renders to HTML → Odoo passes HTML to wkhtmltopdf → wkhtmltopdf converts to PDF. The five common failure modes:

  1. wkhtmltopdf wrong version. Odoo bundles assumptions about 0.12.6 (with patched qt). Other versions (0.12.5, 0.12.7) silently produce blank pages or distort layouts.
  2. CSS that wkhtmltopdf cannot parse. CSS Grid, modern Flex, @container queries, and some position: fixed patterns render blank in wkhtmltopdf.
  3. Network-blocked external assets. The report references https://example.com/font.woff and the Odoo server cannot reach example.com — the resource fails silently and content using that font collapses.
  4. <t t-call="web.external_layout"> outside a <t t-name="..."> wrapper. The layout renders but the inner content is in the wrong scope.
  5. Empty record set. The report iterates o in docs but docs is empty due to a domain bug — the page renders zero records, looks blank.

Step-by-Step Diagnosis

1. Check wkhtmltopdf version.

wkhtmltopdf --version

Required: 0.12.6 (with patched qt). Anything else, install the right one.

2. Render to HTML in dev.

http://localhost:8069/report/html/sale.report_saleorder/14?debug=1

Inspect the rendered HTML. If it is blank, the template is the problem. If it has content, wkhtmltopdf is the problem.

3. Test wkhtmltopdf directly. Save the rendered HTML to a file, then:

wkhtmltopdf --enable-local-file-access page.html out.pdf

If the PDF is still blank, the HTML's CSS or external assets are the cause.

4. Check for CSS incompatibilities. wkhtmltopdf does NOT support:

  • CSS Grid (use Flexbox)
  • CSS variables in some contexts
  • position: sticky
  • Some @media query forms
  • ES6+ JavaScript (it runs an old WebKit)

5. Check the report action.

action = env.ref('sale.action_report_saleorder')
print(action.report_type)        # 'qweb-pdf' or 'qweb-html'
print(action.report_name)        # the QWeb template id
print(action.binding_model_id)   # which model triggers this

Permanent Fix

For wkhtmltopdf version, install the exact version Odoo requires:

# Ubuntu 22.04 / Debian 12
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
sudo apt install -y ./wkhtmltox_0.12.6.1-3.jammy_amd64.deb

# Verify
wkhtmltopdf --version

Pin this version in your provisioning scripts so future server rebuilds keep it.

For CSS incompatibilities, write report CSS for wkhtmltopdf, not for browsers:

/* Avoid: CSS Grid */
.row { display: grid; grid-template-columns: 1fr 1fr; }

/* Use: Float / Flexbox / Tables */
.row::after { content: ""; clear: both; display: table; }
.col { float: left; width: 50%; }

/* Or use an HTML table for layout — wkhtmltopdf renders tables flawlessly */

For complex multi-page layouts, use HTML tables or Bootstrap 5's grid (which Odoo bundles and is wkhtmltopdf-tested).

For external assets, ensure the Odoo server can reach them or inline them. Production servers behind strict egress firewalls often cannot reach Google Fonts; use Odoo's bundled fonts instead:

<style>
    body { font-family: 'Roboto', 'Helvetica', sans-serif; }
</style>

Only reference fonts that ship with the Odoo image.

For the <t t-call="web.external_layout"> issue, wrap correctly:

<template id="report_priority_document">
    <t t-call="web.html_container">
        <t t-foreach="docs" t-as="o">
            <t t-call="web.external_layout">
                <div class="page">
                    <h2>Priority Order: <span t-field="o.name"/></h2>
                    <p>Customer: <span t-field="o.partner_id.name"/></p>
                    <!-- content -->
                </div>
            </t>
        </t>
    </t>
</template>

Both web.html_container and web.external_layout are required wrappers. Missing either breaks rendering subtly.

For empty docs, debug the iteration:

<t t-foreach="docs" t-as="o">
    <p>Document <t t-esc="o.id"/></p>   <!-- temporary debug -->
    ...
</t>

If you see no debug output, docs is empty. Check the report action's _get_report_values in the model.

How to Prevent It

  • Pin wkhtmltopdf in deploy scripts. Every Odoo server's provisioning installs exactly version 0.12.6.1-3 (with patched qt). No silent OS upgrades.
  • CI test that PDFs render non-blank. A simple test that downloads a PDF, checks its byte size is above a threshold (PDFs of one blank page are ~3 KB; a real one is 30+ KB). Catches blank-page regressions cheaply.
  • Avoid modern CSS in reports. Report templates use the same CSS conventions as Odoo's official web.external_layout. When in doubt, copy from Odoo's own reports.
  • Inline external assets. Embed images as base64, fonts as base64-encoded WOFF in CSS. Reduces rendering risk to zero.
  • Test with the real wkhtmltopdf, not the browser preview. Browser preview shows the HTML; wkhtmltopdf is what creates the PDF. Surface bugs by always validating the actual PDF output during dev.
  • Use the --debug-javascript flag during dev. Lets you see JS errors that wkhtmltopdf would otherwise eat.

Frequently Asked Questions

Why does Odoo bundle a specific wkhtmltopdf version?

The official wkhtmltopdf project went unmaintained around 2022. Odoo (and many other projects) standardized on the last known-good "with patched qt" build (0.12.6) because newer releases broke compatibility and security. Until a successor exists (or Odoo migrates to weasyprint or chromium-headless), 0.12.6 is the answer.

Can I switch to a different PDF renderer?

Possible but invasive. The OCA report_xlsx and report_qweb_pdf_chromium modules offer alternatives. Chromium-based rendering supports modern CSS but adds a heavy dependency. Stick with wkhtmltopdf unless you have a specific layout that demands modern CSS.

My report is fine on Linux but blank on Windows dev. Why?

The Windows wkhtmltopdf binary is sometimes a different version. Use Docker or WSL2 to develop against the same wkhtmltopdf as production. Consistency wins.

Why does the same template render blank for some users?

ACL. The user does not have read access to one of the records the template iterates. The template silently iterates an empty recordset for that user, producing a blank page. Add a guard or grant the necessary read access.

How do I add custom CSS only to one report?

Two patterns. Inline <style> inside the template's <t t-call="web.html_container"> block — scoped to that template's render. Or define a separate asset bundle and reference it from a custom paperformat. Inline is simpler and avoids global side effects.

My PDF is huge — 50 MB for a one-page invoice. Why?

Almost always embedded images at full resolution. wkhtmltopdf does not auto-downsample. Resize images before storing or before referencing in the template. A logo at 300 DPI for a print-only PDF is reasonable; 4K screenshots embedded as-is are not.


Need help with a tricky Odoo error? ECOSIRE's Odoo experts have shipped 215+ modules — get expert help.

E

Written by

ECOSIRE Team

Technical Writing

The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.

ECOSIRE

Transform Your Business with Odoo ERP

Expert Odoo implementation, customization, and support to streamline your operations.