nbconvert PDF Export Errors: A Complete Troubleshooting Reference
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:
| Component | Version |
|---|---|
| nbconvert | 7.17.1 |
| nbformat | 5.11.1 |
| Python | 3.14 |
| pandoc | 3.8.3 |
| TeX | TeX Live 2025, BasicTeX (/usr/local/texlive/2025basic) |
| OS | macOS 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 | |
|---|---|---|
| Pipeline | notebook → pandoc → LaTeX → xelatex → PDF | notebook → HTML → headless Chromium → PDF |
| Needs pandoc | Yes | No |
| Needs a TeX distribution | Yes | No |
| Needs Playwright + Chromium | No | Yes |
| Disk cost of dependencies | 4–6 GB for full TeX Live | ~150 MB for Chromium |
| Handles CJK / non-Latin text | Needs font configuration | Works out of the box |
| Typographic quality | Higher | Good 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.htmlWhat 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 pandocThen 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/*/xelatexIf 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-genericFix 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-recommendedIf 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 installfix 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 webpdffix 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 chromiumThe 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.ipynbThat 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.pdfNoSuchKernel: 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 python3What 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 ipykernelThat 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: boomWhat 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.ipynbVerified: 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.ipynbVerified. 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) # TrueFix 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.stygate above, before it ever reaches font selection.
Which path should you actually take?
| Your situation | Do this |
|---|---|
| You need LaTeX typesetting, math-heavy output, or a journal template | Install full MacTeX / texlive-latex-extra and use --to pdf |
| You need a readable PDF of a report, once | Browser 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 packages | Browser 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.ipynbNotes and limitations
- Pinned to nbconvert 7.17.1. Error text changes between versions; check yours with
jupyter nbconvert --versionbefore matching strings on this page. - The LaTeX package list under
tcolorboxreflects a BasicTeX install. A different minimal distribution will surface a different first missing package — the method (read theFile 'X.sty'line, not thel.Nline) is what transfers. - Two fixes on this page are documented but not verified here, and are marked as such
inline: the
sudo tlmgr installpackage fix, and the LaTeX-path CJK font configuration. - If nbconvert works from your terminal but fails from the Jupyter UI, it is almost
always the
PATHcase under “xelatex not found” — the server process has a different environment than your shell.
Related
- Jupyter nbconvert: Convert Notebooks to HTML, PDF & Python — the full format reference, for when you are not debugging
- What is .ipynb_checkpoints? — worth reading before you batch convert a directory, since checkpoint copies will be picked up too
- Install Jupyter Notebook on Mac — getting the environment right in the first place