Aakvatech Limited - Fix ERPNext PDF Letterhead Issues

ERPNext print preview and PDF output do not always behave the same. This guide explains why letterheads may disappear in PDFs when Repeat Header & Footer is enabled, and how developers can fix it.

 · 8 min read

When ERPNext Letterheads Show in Preview but Disappear in PDF

A common ERPNext/Frappe printing issue is this:

The letterhead appears correctly in Print Preview, but disappears when the document is downloaded as PDF. If “Repeat Header and Footer in PDF” is disabled, the letterhead appears again, but the footer moves into the document body.

This is confusing because the print format looks correct in the browser. The root problem is that Print Preview and PDF generation use different rendering paths.

Print Preview is rendered by the browser. PDF generation is rendered server-side, usually through wkhtmltopdf. When Repeat Header and Footer in PDF is enabled, Frappe handles the letterhead and footer differently: it moves them into PDF header/footer regions instead of leaving them as normal body content. ERPNext’s Print Settings documentation confirms that this option is specifically meant to add the header and footer to each PDF page. (Frappe Docs)

The symptom

You may see one of these cases:

Scenario Result
Print Preview Letterhead/logo appears
PDF with Repeat Header & Footer enabled Letterhead/logo missing or clipped
PDF with Repeat Header & Footer disabled Letterhead/logo appears
PDF with Repeat Header & Footer disabled Footer appears too high or inside body content

This does not always mean the Letter Head master is wrong. ERPNext’s Letter Head documentation explains that the Letter Head stores the organization’s logo, address, and related header/footer content for documents like Sales Order, Sales Invoice, Purchase Order, and others. (Frappe Docs)

If the letterhead appears in preview, Frappe has usually resolved the Letter Head correctly. The issue is more likely in the PDF rendering layer.

Why this happens

When Repeat Header & Footer is disabled, the letterhead remains part of the normal document body:

Letter Head → normal print body HTML → browser/PDF renders it as content

When Repeat Header & Footer is enabled, Frappe/wkhtmltopdf uses a different approach:

Letter Head / Footer
→ extracted into PDF header/footer HTML
→ passed to wkhtmltopdf
→ rendered in reserved top/bottom page regions

If the print format CSS removes or disturbs the reserved space, the header may exist but be clipped, hidden, or misaligned.

A real-world example from our investigation involved a Print Format Builder format where the PDF generator was already set to wkhtmltopdf, but the CSS overrode the print format spacing with custom .print-format padding and margin rules. The format had pdf_generator: "wkhtmltopdf", print_format_builder: 1, and custom CSS that included .print-format layout overrides.

The problematic CSS looked like this:

.print-format {
    margin-top: 0mm;
    margin-left: 0mm;
    margin-right: 0mm;
    margin-bottom: 0mm;
    font-size: 9pt !important;
    border: 0px solid black;
    padding: 0.25in;
}

The working fix was:

.print-format {
    padding: 0 !important;
    font-size: 9pt !important;
}

This allowed Frappe/wkhtmltopdf to use the PDF header/footer spacing correctly instead of fighting against extra body padding.

First checks before changing code

Before modifying the print format, verify the basics.

1. Confirm wkhtmltopdf version

Run:

wkhtmltopdf --version

Recommended output:

wkhtmltopdf 0.12.6 (with patched qt)

Several ERPNext/Frappe community posts identify old or unpatched wkhtmltopdf versions as a major cause of missing PDF headers, footers, letterheads, and alignment issues. ERPGulf specifically lists symptoms such as “Letter head footer not printing” and “Letter head alignment not correct,” and recommends upgrading to wkhtmltopdf 0.12.6 while also ensuring server hairpin access. (ERPGulf)

A Frappe forum thread also points developers to check wkhtmltopdf -V, noting that 0.12.5 with patched Qt or higher is expected and 0.12.6 is preferred. (Frappe Forum)

2. Confirm the Letter Head is enabled and default

Check the Letter Head master:

select name, disabled, is_default
from `tabLetter Head`;

You should have a valid default Letter Head:

disabled = 0
is_default = 1

3. Confirm the image is reachable from the server

If the Letter Head uses an image like:

<img src="/files/MAIN-PNG-TRANSPARENT.png">

test it from the server:

curl -I "https://your-site.com/files/MAIN-PNG-TRANSPARENT.png"

The response should be:

HTTP/1.1 200 OK

If the server cannot reach the URL, the browser preview may still work while the PDF output fails. ERPGulf also highlights that wkhtmltopdf needs the server to access its own site through the configured domain, firewall, and Nginx path. (ERPGulf)

Use absolute URLs for letterhead images where possible:

<img src="https://your-site.com/files/MAIN-PNG-TRANSPARENT.png" style="height:100px;">

Key diagnostic: turn Repeat Header/Footer off

If the PDF letterhead disappears only when Repeat Header and Footer in PDF is enabled, you have identified the failing layer.

A useful test matrix:

Test Meaning
Preview shows logo, PDF does not PDF rendering issue
PDF works when Repeat Header/Footer is disabled Header/footer extraction issue
Plain text letterhead also disappears Not an image-loading issue
Increasing/removing padding fixes it Layout spacing issue
wkhtmltopdf is patched and current Not a binary-version issue

A Frappe forum user described a similar case where the header and footer appeared in web preview but not in PDF. They tried id="header-html" and id="footer-html" but the header/footer only showed when {{ letter_head }} and {{ footer }} were printed outside those repeated header/footer divs. (Frappe Forum)

Another user reported that unchecking “Repeat Header and Footer in PDF” made the letterhead work, although email/PDF attachments still had related issues. (Frappe Forum)

The fix: do not fight Frappe’s PDF margins with .print-format padding

When Repeat Header/Footer is enabled, avoid heavy layout overrides on .print-format.

Avoid this:

.print-format {
    margin-top: 0mm;
    margin-left: 0mm;
    margin-right: 0mm;
    margin-bottom: 0mm;
    padding: 0.25in;
}

Use this instead:

.print-format {
    padding: 0 !important;
    font-size: 9pt !important;
}

Then use the Print Format margin fields or Print Settings to control the printable area, rather than mixing Frappe margin fields with custom CSS padding.

In the investigated case, removing the .print-format padding fixed both the letterhead visibility and the alignment. The PDF did not need manually increased margins once the conflicting padding was removed.

If the header is still clipped

If removing padding is not enough, reserve more top/bottom space.

Try:

.print-format {
    padding: 0 !important;
    font-size: 9pt !important;
    margin-top: 35mm !important;
    margin-bottom: 25mm !important;
}

Then reduce gradually.

Use this only if needed. If padding: 0 solves the issue, prefer the simpler fix.

Avoid malformed HTML in print formats

Browsers are forgiving. wkhtmltopdf is less forgiving.

This kind of malformed table can render in preview but cause unpredictable PDF behavior:

<table style="width: 100%;">
  <tr>
    <td>...</td>
    <td>...</td>
    <td>...</td>
  </td>
</table>

The closing tag should be </tr>, not </td>:

<table style="width: 100%;">
  <tr>
    <td>...</td>
    <td>...</td>
    <td>...</td>
  </tr>
</table>

Also avoid nesting <p> tags inside other <p> tags. Use <div> for layout blocks:

<td style="width: 50%; vertical-align: bottom !important;">
  {% if doc.select_print_heading is not none %}
    <div class="h2 text-center"><b>{{ doc.select_print_heading }}</b></div>
  {% else %}
    <div class="h4 text-center"><b>SALES ORDER - {{ doc.name }}</b></div>
  {% endif %}
</td>

Malformed HTML may not be the primary cause, but it can amplify PDF-only rendering issues.

Use this sequence when debugging letterhead issues:

1. Confirm the Letter Head is enabled and default.
2. Confirm Print Settings → With Letterhead is enabled.
3. Confirm Repeat Header and Footer in PDF behavior.
4. Check wkhtmltopdf --version.
5. Confirm it says “with patched qt”.
6. Check whether the issue affects images only or plain text too.
7. Test whether disabling Repeat Header/Footer makes the logo appear.
8. Remove .print-format padding/margin overrides.
9. Use absolute URLs for letterhead images.
10. Fix malformed HTML in custom print blocks.
11. Clear cache and regenerate the PDF.

Useful commands:

wkhtmltopdf --version
bench --site your-site clear-cache
bench restart
curl -I "https://your-site.com/files/your-logo.png"

Practical final CSS

For most cases, start with this:

.print-format {
    padding: 0 !important;
    font-size: 9pt !important;
}

If the header still clips:

.print-format {
    padding: 0 !important;
    font-size: 9pt !important;
    margin-top: 35mm !important;
    margin-bottom: 25mm !important;
}

If the document uses a large logo, reduce the logo height first before increasing margins too much:

<img src="https://your-site.com/files/company-logo.png" style="height:80px;">

When to avoid Repeat Header/Footer

If the document is usually one page and does not require repeated headers and footers, the simpler approach is to disable Repeat Header/Footer and render the letterhead/footer directly in the print body.

But if the document spans multiple pages and the header/footer must repeat, keep Repeat Header/Footer enabled and make the print format PDF-safe.

Reference articles and discussions

Developers facing this issue may find these references useful:

  1. ERPNext Print Settings documentation explains the Repeat Header and Footer in PDF option and confirms that it adds the header and footer to each PDF page. (Frappe Docs)

  2. ERPNext Letter Head documentation explains how Letter Head stores the organization’s logo, name, address, and related content used in transaction print formats. (Frappe Docs)

  3. ERPGulf’s PDF printing article lists letterhead/footer misalignment and missing footer problems, recommends checking wkhtmltopdf --version, and highlights the need for server hairpin access. (ERPGulf)

  4. A Frappe forum thread reports header/footer showing in preview but not in PDF, with header-html / footer-html behavior being the key issue. (Frappe Forum)

  5. Another Frappe forum thread reports header showing in print preview but missing in PDF/email output, with community guidance to verify browser settings and wkhtmltopdf version. (Frappe Forum)

  6. A Frappe forum discussion reports Letter Head visible in print view but not PDF even with wkhtmltopdf 0.12.6, showing that version alone does not always solve the problem. (Frappe Forum)

  7. A Frappe forum post about Letter Head not repeating on every page documents the patched Qt wkhtmltopdf requirement for repeated headers and footers. (Frappe Forum)

  8. A Frappe forum discussion on custom print formats notes common problems with repeated letterheads, visible-pdf, and footers appearing in the body instead of the bottom of the PDF. (Frappe Forum)

  9. A Stack Overflow question from 2025 shows that developers still hit issues with #header-html, #footer-html, and Repeat Header/Footer behavior in custom Frappe print formats. (Stack Overflow)

  10. A Frappe forum thread on PDF footer not printing summarizes common attempted fixes: hostname settings, toggling Repeat Header/Footer, and wkhtmltopdf version checks. (Frappe Forum)

Final recommendation

When a letterhead appears in preview but disappears in PDF only when Repeat Header and Footer is enabled, do not immediately assume the Letter Head master is broken. First inspect the print format CSS.

In many cases, the fix is simple:

.print-format {
    padding: 0 !important;
    font-size: 9pt !important;
}

Let Frappe and wkhtmltopdf manage the PDF header/footer regions, keep custom HTML valid, and use absolute URLs for letterhead images. This produces more predictable PDFs and avoids the common trap where browser preview looks perfect but the downloaded PDF does not.


This blog was created with assistance from AI but articulated and verified by a human.


No comments yet.

Add a comment
Ctrl+Enter to add comment