AboutBlogMediaTags

nbconvert PDF Export Errors: A Complete Troubleshooting Reference

Runcell Team,

nbconvert PDF Export Errors: A Complete Troubleshooting Reference

jupyter nbconvert --to pdf fails more often than it succeeds on a fresh machine, and the error you get back is frequently not about the thing that is actually missing.

This page is a lookup table for the errors you are most likely to hit. Except where a section says otherwise, each one was reproduced on a clean virtual environment and the error text is copied from that run rather than paraphrased — long logs are trimmed to the relevant lines, marked with .... Two fixes on this page could not be verified in that environment; both say so inline. Search this page for your exact error string.

Environment used for every reproduction on this page:

ComponentVersion
nbconvert7.17.1
nbformat5.11.1
Python3.14
pandoc3.8.3
TeXTeX Live 2025, BasicTeX (/usr/local/texlive/2025basic)
OSmacOS 15, arm64

Start here: you are on one of two completely different code paths

Almost all confusion about nbconvert PDF errors comes from not knowing which of these two pipelines you invoked. They share nothing but the output extension.

--to pdf--to webpdf
Pipelinenotebook → pandoc → LaTeX → xelatex → PDFnotebook → HTML → headless Chromium → PDF
Needs pandocYesNo
Needs a TeX distributionYesNo
Needs Playwright + ChromiumNoYes
Disk cost of dependencies4–6 GB for full TeX Live~150 MB for Chromium
Handles CJK / non-Latin textNeeds font configurationWorks out of the box
Typographic qualityHigherGood enough for most reports

If you do not specifically need LaTeX typesetting, --to webpdf is the shorter road, and several of the errors below simply do not exist on it.

If you would rather not install either toolchain, the Runcell ipynb → PDF converter  runs the conversion in the browser — no pandoc, no TeX, no Chromium download.


PandocMissing: Pandoc wasn't found.

Full error:

File ".../nbconvert/utils/pandoc.py", line 75, in get_pandoc_version raise PandocMissing() nbconvert.utils.pandoc.PandocMissing: Pandoc wasn't found. Please check that pandoc is installed: https://pandoc.org/installing.html

What is actually happening. This is the first gate on the --to pdf path, and it fires before nbconvert ever looks for a LaTeX engine. That ordering matters: if both pandoc and xelatex are missing, you will see this error and nothing about LaTeX. Every “install xelatex” answer you find will appear not to work, because you never got far enough for xelatex to be the problem.

Fix:

# macOS brew install pandoc # Debian / Ubuntu sudo apt-get install pandoc # conda conda install -c conda-forge pandoc

Then re-run. Expect to hit the next gate — that is normal progress, not a new failure.


OSError: xelatex not found on PATH

Full error:

File ".../nbconvert/exporters/pdf.py", line 120, in run_command raise OSError(msg) OSError: xelatex not found on PATH, if you have not installed xelatex you may need to do so. Find further instructions at https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex.

What is actually happening. pandoc succeeded and produced a .tex file. nbconvert now wants to compile it, and there is no TeX distribution installed — or there is one, but its bin directory is not on PATH for this shell.

Check which of the two it is before installing anything:

which xelatex ls /Library/TeX/texbin/xelatex # macOS, TeX Live / MacTeX ls /usr/local/texlive/*/bin/*/xelatex

If the files exist but which finds nothing, it is a PATH problem, not a missing install. This is extremely common when nbconvert is launched from a Jupyter server, a cron job, or an IDE — those processes often do not inherit your shell profile.

Fix A — put an existing TeX on PATH:

export PATH="/Library/TeX/texbin:$PATH"

Fix B — install TeX. Be aware of the size before you commit:

# macOS, minimal (~100 MB) — but see the next section, it is not enough on its own brew install --cask basictex # macOS, complete (~4 GB) brew install --cask mactex # Debian / Ubuntu sudo apt-get install texlive-xetex texlive-fonts-recommended texlive-plain-generic

Fix C — skip LaTeX entirely. Use --to webpdf (see below), or the browser-based converter  if this is a one-off export and 4 GB of TeX is not a trade you want to make.


! LaTeX Error: File 'tcolorbox.sty' not found.

This is the one that wastes the most time, because the useful part of the message and the part your eye lands on are in two different places.

Error output, trimmed to the relevant lines:

[NbConvertApp] Writing 21062 bytes to notebook.tex [NbConvertApp] Building PDF [NbConvertApp] Running xelatex 3 times: ['xelatex', 'notebook.tex', '-quiet'] [NbConvertApp] CRITICAL | xelatex failed: ['xelatex', 'notebook.tex', '-quiet'] This is XeTeX, Version 3.141592653-2.6-0.999997 (TeX Live 2025) ... (/usr/local/texlive/2025basic/texmf-dist/tex/latex/base/article.cls Document Class: article 2024/06/29 v1.4n Standard LaTeX document class ! LaTeX Error: File `tcolorbox.sty' not found. Type X to quit or <RETURN> to proceed, or enter new name. (Default extension: sty) Enter file name: ! Emergency stop. <read *> l.4 \usepackage {parskip} % Stop auto-indenting (to mimic markdown behavi... No pages of output.

Read that output again. TeX names the missing file correctly — tcolorbox.sty — near the top. But the last thing printed, and the thing that looks like a location, is l.4 \usepackage{parskip}. That is a different package.

TeX is not claiming parskip is missing. l.4 is where the input reader had got to when it hit the emergency stop, not the line that caused it. But it is the line most people copy into a search box, and “parskip not found” leads nowhere near the actual problem.

Rule: read the ! LaTeX Error: File 'X.sty' not found. line. The l.N line at the bottom is context, not the cause.

What is actually happening. You have a TeX installation, but it is a minimal one. BasicTeX and texlive-base ship a small package set; nbconvert’s default LaTeX template pulls in packages that are not in it. tcolorbox is the first one it hits, and there are usually more behind it — fixing one reveals the next.

Fix A — install the missing packages:

# macOS BasicTeX — requires admin rights sudo tlmgr update --self sudo tlmgr install tcolorbox pdfcol adjustbox titling enumitem soul ucs collection-fontsrecommended # Debian / Ubuntu — install the fuller package set instead of hunting one by one sudo apt-get install texlive-latex-extra texlive-fonts-recommended

If a package you install reveals another missing .sty, repeat with the new name. The loop terminates, but it can take several rounds on a minimal install.

Verification note: the error above was reproduced on this machine. The sudo tlmgr install fix was not run here, because it needs administrator rights on the system TeX tree. The package list is the documented BasicTeX gap, not something this page verified end to end. The --to webpdf fix below was verified.

Fix B — stop fighting the package tree. If you are exporting a report, not publishing a paper, the LaTeX path is a lot of dependency management for a result nobody will inspect for kerning. Use --to webpdf, or the Runcell ipynb → PDF converter  if you want the PDF without installing anything at all.


RuntimeError: Playwright is not installed to support Web PDF conversion.

Full error:

File ".../nbconvert/exporters/webpdf.py", line 110, in main raise RuntimeError(msg) from e RuntimeError: Playwright is not installed to support Web PDF conversion. Please install `nbconvert[webpdf]` to enable.

What is actually happening. You asked for the browser path, but the browser is not there. Two separate things are needed — the Python package and a Chromium binary — and installing the [webpdf] extra only provides the first.

Fix:

pip install "nbconvert[webpdf]" python -m playwright install chromium

The second command is the one people skip. Without it, you get a Playwright launch failure rather than this import error, which reads differently and sends you looking in the wrong place.

nbconvert can also fetch Chromium for you at conversion time:

jupyter nbconvert --to webpdf --allow-chromium-download notebook.ipynb

That still requires the [webpdf] extra first. Prefer the explicit playwright install chromium in CI, where you want the download to happen at image build time rather than on every run.

Verified working afterwards:

$ python -m nbconvert --to webpdf plain.ipynb [NbConvertApp] Building PDF [NbConvertApp] PDF successfully created [NbConvertApp] Writing 40070 bytes to plain.pdf

NoSuchKernel: No such kernel named python3

This one appears when you add --execute, and it is not really a PDF error — but it is the most common thing standing between people and a PDF of freshly run results.

Full error:

File ".../jupyter_client/kernelspec.py", line 287, in get_kernel_spec raise NoSuchKernel(kernel_name) jupyter_client.kernelspec.NoSuchKernel: No such kernel named python3

What is actually happening. The notebook’s metadata asks for a kernel named python3. Your virtual environment has nbconvert installed but never registered a kernel spec, so there is nothing by that name to start. Installing nbconvert does not install a kernel.

Fix:

pip install ipykernel

That is usually enough — ipykernel provides a python3 spec. To register the venv under its own name instead:

python -m ipykernel install --user --name my-project --display-name "My Project"

Then either pass --ExecutePreprocessor.kernel_name=my-project or update the notebook’s kernel metadata.


Conversion aborts on the first cell that raises

Symptom: --execute stops partway and prints the cell’s traceback instead of writing output.

Cell In[1], line 1 ----> 1 raise ValueError('boom') ValueError: boom

What is actually happening. This is intended behaviour: by default, a cell error halts the whole conversion, so you never silently ship a report built from a failed run.

Fix — only if you actually want the errors in the output:

jupyter nbconvert --to html --execute --allow-errors notebook.ipynb

Verified: with --allow-errors, the same failing notebook completes and writes 277,862 bytes of HTML, with the traceback rendered inline as a cell output.

Related: a long-running cell will hit the default timeout instead. Raise it with --ExecutePreprocessor.timeout=600.


Chinese, Japanese, Korean, or other non-Latin text

Symptom on the LaTeX path: blank boxes, missing glyphs, or a font-related xelatex failure.

What is actually happening. The default nbconvert LaTeX template does not configure a CJK-capable font. xelatex can handle Unicode, but it needs to be told which font to use for those ranges, and the stock template does not do it.

Fix A — use the browser path, which uses the system’s font stack and needs no configuration:

jupyter nbconvert --to webpdf notebook.ipynb

Verified. A notebook containing # 季度分析报告 and print('结果:完成') converted cleanly to a 67,661-byte PDF. Extracting the text back out of the resulting PDF returns the original characters as real text, not as images or replacement boxes:

from pypdf import PdfReader text = PdfReader("cjk.pdf").pages[0].extract_text() print("季度分析报告" in text) # True print("结果" in text) # True

Fix B — configure a CJK font on the LaTeX path. This means supplying a custom template that sets \setCJKmainfont, plus having xeCJK and a suitable font installed. It is doable, but it is meaningfully more work than switching paths.

Verification note: Fix A was verified as shown. The LaTeX-path CJK failure was not independently reproduced here — on this machine the LaTeX path stops at the tcolorbox.sty gate above, before it ever reaches font selection.


Which path should you actually take?

Your situationDo this
You need LaTeX typesetting, math-heavy output, or a journal templateInstall full MacTeX / texlive-latex-extra and use --to pdf
You need a readable PDF of a report, onceBrowser converter  — nothing to install
You need PDFs in CI or a batch script--to webpdf; Chromium is ~150 MB vs 4 GB for TeX
Your notebook has CJK or other non-Latin text--to webpdf
You are on a locked-down machine and cannot install system packagesBrowser converter 
You actually wanted HTML, not PDF--to html, or the ipynb → HTML converter 
You wanted the code as a script--to script, or the ipynb → Python converter 

The honest summary: the LaTeX path is worth its setup cost if you will export PDFs regularly and care about typesetting. For a one-off, the dependency chain — pandoc, a TeX distribution, and a package set that reveals itself one missing .sty at a time — costs more than the PDF is worth.


Reproducing these yourself

The reproduced errors on this page came from this setup. If you want to test a fix against a known-good baseline rather than against your real notebook:

python -m venv .venv .venv/bin/pip install nbconvert nbformat
# make_test_notebooks.py import nbformat as nbf nb = nbf.v4.new_notebook() nb.cells = [ nbf.v4.new_markdown_cell("# Quarterly analysis\n\nA short report."), nbf.v4.new_code_cell("import pandas as pd\ndf = pd.DataFrame({'a':[1,2,3]})\ndf.sum()"), ] nbf.write(nb, "plain.ipynb") cjk = nbf.v4.new_notebook() cjk.cells = [ nbf.v4.new_markdown_cell("# 季度分析报告\n\n本报告包含中文字符。"), nbf.v4.new_code_cell("print('结果:完成')"), ] nbf.write(cjk, "cjk.ipynb")

Then reproduce each gate by controlling what is on PATH:

# No pandoc, no TeX -> PandocMissing env PATH=".venv/bin:/usr/bin:/bin" .venv/bin/python -m nbconvert --to pdf plain.ipynb # pandoc but no TeX -> xelatex not found on PATH env PATH=".venv/bin:/opt/homebrew/bin:/usr/bin:/bin" .venv/bin/python -m nbconvert --to pdf plain.ipynb # Full PATH, minimal TeX -> missing .sty env PATH=".venv/bin:/opt/homebrew/bin:/Library/TeX/texbin:/usr/bin:/bin" .venv/bin/python -m nbconvert --to pdf plain.ipynb

Notes and limitations


© Runcell.RSS