[BUG] Read tool's PDF support requires poppler-utils but it's undocumented, usually absent, and not detected after install

Status Open
Reported on v2.1.33
Maintainer reply None cached
Activity 17 comments · opened Feb 6, 2026

What's Wrong?

The Read tool's description says "This tool can read PDF files (.pdf)", but PDF reading depends on poppler-utils (specifically pdftoppm), which:

  1. Is not installed by default in common development environments — In our case, a container based on node:22-bookworm did not have it. It is not part of coreutils and requires explicit installation.
  2. Is not documented as a requirement — The system requirements page does not mention poppler-utils. The Read tool's description promises PDF support with no caveats.
  3. Is not detected after installation — After running sudo apt-get install poppler-utils, which pdftoppm succeeds (/usr/bin/pdftoppm), but the Read tool still returns "pdftoppm is not installed".

What Should Happen?

Either:

  • Bundle or auto-install the dependency so PDF reading works out of the box, or
  • Document it as a system requirement for PDF support, or
  • At minimum, detect it correctly after installation without requiring a restart

Error Messages/Logs

pdftoppm is not installed. Install poppler-utils (e.g. `brew install poppler` or `apt-get install poppler-utils`) to enable PDF page rendering.

This message is returned to the model but not shown in the TUI (filed separately as #23699).

Steps to Reproduce

  1. Start Claude Code in an environment without poppler-utils (tested in a container based on node:22-bookworm)
  2. Ask Claude to read a PDF file
  3. Read fails with "pdftoppm is not installed"
  4. Run sudo apt-get install poppler-utils
  5. Verify: which pdftoppm/usr/bin/pdftoppm
  6. Ask Claude to read the same PDF again
  7. Read fails again with the same error

Model: Opus

Is this a regression?: I don't know

Claude Code Version: 2.1.33

Platform: Anthropic API

Operating System: Ubuntu/Debian Linux

Terminal/Shell: iTerm2

Additional Information

  • Related: #23699 (Read tool errors are not shown in TUI)
  • The workaround is curl + pdftotext + Read on the resulting text file — 3 tool calls for what should be a single Read

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

View original on GitHub ↗

15 Comments

github-actions[bot] · 6 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/16435
  2. https://github.com/anthropics/claude-code/issues/14817
  3. https://github.com/anthropics/claude-code/issues/23699

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

carrotRakko · 6 months ago

Not a duplicate of the suggested issues:

  • #16435: Silent exit when ripgrep/fzf is missing in Docker. Different undocumented dependency, different symptom (exit vs. tool failure), different tool (CLI startup vs. Read).
  • #14817: Plugin's undocumented jq dependency on Windows. Matched on the "undocumented dependency" concept, but entirely different component.
  • #23699: Read tool errors not shown in TUI. Related (we filed both), but a separate issue — #23699 is about error display, this issue is about the dependency itself being undocumented, absent by default, and not detected after install.

✍️ Author: Claude Code with @carrotRakko (AI-written, human-approved)

BaseBlank · 6 months ago

After v2.1.33, I can't use Windows Claude Code to read PDF documents: the error message is as follows:
● The Read tool's PDF renderer (pdftoppm) isn't installed on this Windows system. Let me extract the PDF content using
Python instead.

renstroost · 6 months ago

I am also put out by this same problem. please address this @anthropic! as of 2.1.63 annoying quiet failures to understand PDFs. it is also a problem that this requires a GPL install (a problem for people who ship code). That is probably at the root of why you are not shipping it but this is a poor way to treat your users. Include your dependencies, or at least be up front about it!

Whoever decided to do this should be put in a room with RMS and made to listen to the free software song for a week.

matt-lachman-trss · 6 months ago

I just ran into this as well.

duaneking · 5 months ago

This is a full regression it used to be able to read PDF'S easily

skylatian · 5 months ago

+1 here, using opus on 2.1.76

pain-Medicine · 5 months ago

+1, has been happening for the last 1 month+

ejhg · 5 months ago

This is unacceptable... (I caught CC just in time when it was trying to brew install poppler onto my machine...)

OBugroviy · 5 months ago

Same issue on version 2.1.81 for VS Code on Windows
I had to install it using winget install poppler, and then it worked.

alagonterie · 3 months ago

+1 reproducing on Windows 11 — the same three sub-bugs the OP flagged all hit:

1. Not bundled. Hit pdftoppm failed: Command 'pdftoppm' not found or is in an unsafe location (current directory) on a fresh Windows install. The Read tool's description (This tool can read PDF files (.pdf)) gave no hint that poppler was a hard requirement.

2. Not documented for Windows. The setup page lists nothing about poppler. On Windows, the install path most users will reach for is scoop install poppler or choco install poppler — worth adding alongside brew install poppler / apt-get install poppler-utils if this stays a documented dependency.

3. Not detected after install (in-session). After scoop install poppler (which puts pdftoppm.exe on PATH at ~\scoop\shims\pdftoppm.exe and is verifiable from a fresh shell), the same Claude Code session still returns the original error on re-Read. Killing and restarting the Claude Code process picks it up — so it looks like PATH gets snapshotted at session start.

Environment:

  • Claude Code: 2.1.140
  • Platform: Windows 11 Enterprise (10.0.26200), Git Bash
  • Poppler: 26.02.0-0 via scoop, verified pdftoppm -v works from a sibling shell

Suggested fixes (in priority order, IMO):

  1. Detect missing pdftoppm up front and surface a one-line "install poppler / poppler-utils for PDF support" to the user instead of returning the cryptic error to the model.
  2. Re-resolve PATH per-tool-invocation, not per-session, so users don't have to restart after installing.
  3. Bonus: if pdftoppm is missing but pdftotext is available, fall back to text-only extraction so the agent can at least read the contents (loses vision, but better than nothing).

Happy to provide more detail / open a separate Windows-specific issue if you'd prefer to keep this one Linux-scoped.

feliciocarrico · 1 month ago

Confirming this on Windows 11 (native, not Docker), Claude Code 2.1.162 —
the Read tool's PDF renderer ignores the PATH from every source.

poppler 26.02.0. I made pdftoppm discoverable in every possible way,
fully restarting Claude Code after each change:

  • Added the poppler bin to the User PATH
  • Added it to the Machine / system PATH
  • Copied the whole bin to C:\Program Files\poppler\bin

In the shell Claude Code spawns, every check passes:

  • where.exe pdftoppm → resolves it (both locations)
  • $env:PATH contains the poppler dirs
  • pdftoppm -vpdftoppm version 26.02.0

Yet Read on any .pdf still returns
pdftoppm is not installed. Install poppler-utils ..., even after a full restart.

So the renderer resolves the binary through an isolated lookup that reflects
neither the process PATH, the User PATH, the Machine PATH, nor C:\Program Files.
There's no documented env var (e.g. POPPLER_PATH) or setting to point it at the
binary — which makes PDF reading effectively unusable on Windows even with poppler
correctly installed.

Working workaround: shell out to poppler and read the resulting image —
pdftoppm -png -r 150 -f N -l N "file.pdf" out then read out-N.png.

Robertstuffers · 1 month ago

I ran into this on Windows 11 (native install, Claude Code 2.1.205/2.1.206) and dug into the bundled code. I believe I found the root cause of the "not detected after install" behavior, at least for Windows — plus a cross-platform robustness bug in the same detection path.

Symptom: the Read tool keeps returning pdftoppm is not installed. Install poppler-utils… even though poppler is installed, its directory is on PATH, pdftoppm -v exits 0 from every shell — including shells spawned by the very same Claude Code session — and where.exe pdftoppm resolves fine from those shells. I also verified (by reading the environment block of the running claude.exe via its PEB) that the main process itself was started with the poppler directory in PATH.

What the code does (minified identifiers from the 2.1.206 bundle):

  1. PDF support is probed by a function (FDy) that runs pdftoppm -v through the internal exec helper (zrzn) and considers it available iff code === 0 || (code !== 127 && stderr.length > 0).
  2. Bug A — sticky negative cache (Windows). Bare command names are resolved by a Windows resolver (wAn) that shells out to %SYSTEMROOT%\System32\where.exe <name> and caches the result in an in-memory map. When where.exe exits 1, null is cached permanently for the process lifetime — no TTL, and the cache-bypass parameter is never set on this call path (LSe(e) is called with one argument). So a single transient resolution failure (in my case most likely at session start, while the auto-updater was concurrently replacing claude.exe) poisons the whole session: every subsequent PDF read reports "pdftoppm is not installed", and installing poppler mid-session can never fix it — which is exactly the "not detected after install" symptom in this issue. Only a restart helps.
  3. Bug B — stderr discarded (all platforms). FDy calls the exec helper with {timeout: 5000, useCwd: false} and without preserveOutputOnError: true. In zn, when the child exits non-zero, stdout/stderr are replaced by empty strings (if(!o) return {stdout:"", stderr:"", code}). That means the stderr.length > 0 fallback in the availability check can never trigger; detection silently reduces to "pdftoppm -v must exit 0". Any poppler build/wrapper whose -v exits non-zero is reported as "not installed" even though the check clearly intends to accept it.

Evidence it's the cache and not the environment: while a long-running session kept failing, a freshly spawned headless instance on the same machine — claude -p "Read page 1 of <pdf>" — rendered the PDF without problems.

Suggested fixes:

  • Don't cache negative executable-resolution results (or give them a short TTL / re-probe on the next Read attempt).
  • Pass preserveOutputOnError: true in the pdftoppm availability probe so the stderr fallback works as intended.
  • Document poppler-utils as the (optional) dependency for PDF page rendering, and include the underlying spawn/resolution error in the message instead of the generic "not installed".

Related: #42330 (same sticky-cache failure mode, misattributed to PATH), #42248 (macOS desktop app; different trigger — minimal PATH in app-launched processes — but the same opaque detection makes it undiagnosable).

feliciocarrico · 1 month ago

@Robertstuffers — thank you, this is one of the clearest root-cause writeups I've seen on this bug. 🙏

I can confirm your sticky-cache theory reproduces on Windows 11 with an even older build:

  • Claude Code 2.1.162
  • poppler 26.02.0 at C:\Program Files\poppler\bin (plus a second copy on PATH); where.exe pdftoppm resolves both and pdftoppm -v exits 0 from every shell, including ones spawned by the session.
  • Despite that, the Read tool intermittently reports pdftoppm is not installed, and once it does, reinstalling poppler or fixing PATH mid-session changes nothing.
  • Restarting the session is the only thing that clears it — exactly what your Bug A (in-memory negative cache, no TTL) predicts. A fresh claude -p on the same machine renders the PDF without issue.

The PATH red-herring in the earlier duplicates (#42330, #42248) lines up with your point perfectly — this is resolution-caching, not PATH. Really hope the maintainers pick up your two fixes (don't cache negative resolutions + preserveOutputOnError: true). Thanks again for digging into the bundle.

swc200git · 26 days ago

Confirming this also shows up via the pages parameter specifically, on Windows, with no poppler-utils installed at all (not a detection failure, genuinely absent). A plain oversized-PDF read fails with a clean size-cap error; retrying with pages set as a fallback hits this pdftoppm is not installed error instead, a completely different failure mode for what looks like the same underlying problem. Neither error points at the other, so it took two failed attempts to find the actual fix (re-export/compress the file, skip pages entirely). Might be worth the size-cap error mentioning that pages isn't a reliable workaround, given how easy it is to reach for.

Showing cached comments. Read the full discussion on GitHub ↗