TesseractNotFoundError: tesseract is not installed or it's not in your PATH
pytesseract is only a Python wrapper.
pip install pytesseract does not install Tesseract, so
install the program too: brew install tesseract on a Mac,
apt-get install tesseract-ocr on Debian or Ubuntu, or the
UB Mannheim installer on Windows. If you already did that, your Python
process cannot see it. I got this exact error 5 ways on a Mac with
Tesseract installed the whole time.
No install: try it, $0.006 a page
First, ask Python what it can see
The first words of the error are a clue. pytesseract builds the
message from tesseract_cmd, the name it tried to run. So
tesseract is not installed means it searched your PATH,
tesseract.exe is not installed means someone set that
name, and C:\Program Files\... means a hard-coded path.
Then run this from the place that fails: the same IDE button, job or container. A new terminal tells you nothing, because a terminal is where it already works.
import os, shutil, sys
import pytesseract
cmd = pytesseract.pytesseract.tesseract_cmd
print("python:", sys.executable)
print("PATH:", os.environ.get("PATH"))
print("tesseract_cmd:", repr(cmd))
print("found at:", shutil.which(cmd))
print("version:", pytesseract.get_tesseract_version())
This is the broken run, with launchd's PATH (traceback cut):
python: /private/tmp/seo29/venv/bin/python
PATH: /usr/bin:/bin:/usr/sbin:/sbin
tesseract_cmd: 'tesseract'
found at: None
pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your PATH. See README file for more information.
This is the working run, with Homebrew's folder added:
python: /private/tmp/seo29/venv/bin/python
PATH: /opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin
tesseract_cmd: 'tesseract'
found at: /opt/homebrew/bin/tesseract
version: 5.5.3
shutil.which returned None for all 6 bad
values I tried, including the ones in cause 8. If
found at shows None, the problem is in the
lines above it.
The 7 causes I reproduced, and one look-alike
pytesseract 0.3.13 on Python 3.14.7, Tesseract 5.5.3 from Homebrew, on an Apple silicon Mac. Causes 3 to 7 raised this exact error with Tesseract installed, each in a new process with its own small environment. Causes 1 and 2 ran in Docker. Cause 8 is the same kind of mistake with a different error.
| Cause | The error starts with | Fix | After the fix |
|---|---|---|---|
| 1. Only the wrapper is installed | tesseract is not installed |
Install the program | Ran |
2. pip install tesseract |
tesseract is not installed |
That is a different package. See cause 1 | Ran |
| 3. The process has a shorter PATH | tesseract is not installed |
Add the folder to its PATH | Ran |
| 4. A path from another machine |
C:\Program Files\... or
/usr/local/bin/tesseract
|
shutil.which |
Ran |
5. A Windows path with no r |
...Tesseract-OCR esseract.exe |
Raw string or forward slashes | String is right. Not run on Windows |
| 6. The wrong setting name | tesseract is not installed |
pytesseract.pytesseract.tesseract_cmd |
Ran |
7. ~ in the path |
~/bin/tesseract is not installed |
os.path.expanduser |
Ran |
| 8. Look-alike: a folder, not the program | PermissionError: [Errno 13] |
The full path of the program file | Ran |
1. Only the wrapper is installed
On a clean python:3.13-slim image,
pip install pytesseract pillow finished without a
complaint. which tesseract then found nothing, and the
first OCR call raised the error. pip adds a command named
pytesseract, not one named tesseract. The
pytesseract README lists Tesseract as something you install yourself.
# Mac, with Homebrew
brew install tesseract
# Debian or Ubuntu
sudo apt-get install -y tesseract-ocr
# Alpine: the English data is a separate package
apk add tesseract-ocr tesseract-ocr-data-eng
The package names are easy to get wrong. On Debian,
apt-get install tesseract stopped with
E: Unable to locate package tesseract. On Alpine,
apk add tesseract said
tesseract (no such package).
For Windows, the Tesseract docs point to the
UB Mannheim installer. I have no Windows machine, so I did not run it. The docs say you
may have to add its folder to PATH, probably
C:\Program Files\Tesseract-OCR. Setting
tesseract_cmd is the other way.
2. pip install tesseract
This looks right and installs the wrong thing. On PyPI,
tesseract 0.1.3 is a science package with the summary
"Tesselation based Recovery of Amorphous halo Concentrations". The
install worked, there was still no tesseract command, and
pytesseract raised this same error.
pip install tesseract-ocr is no way out either: it failed
with Failed to build installable wheels. I tried both in
a throwaway container.
3. The process has a shorter PATH
This is the "it works in my terminal" case. Your terminal gets its
PATH from your shell setup. A background job does not. I ran a real
launchd job on this Mac, and it got
PATH=/usr/bin:/bin:/usr/sbin:/sbin, with no Homebrew
folder. It raised this error with Tesseract installed. Adding the
folder to the job's plist fixed it:
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/bin:/bin</string>
</dict>
Or fix it in Python. pytesseract passes os.environ along
on each call, so this worked both before and after the import:
import os
os.environ["PATH"] = "/opt/homebrew/bin:" + os.environ["PATH"]
4. A path from another machine
A line copied from a tutorial keeps working until it runs somewhere
else. On this Mac, 3 paths raised the error, each with the bad path in
the message: the Windows path from tutorials, the Intel Mac path
/usr/local/bin/tesseract, and a Homebrew path with an old
version in it,
/opt/homebrew/Cellar/tesseract/5.5.2/bin/tesseract. Look
the path up instead, and keep a fallback for jobs:
import shutil
import pytesseract
pytesseract.pytesseract.tesseract_cmd = shutil.which("tesseract") or "/opt/homebrew/bin/tesseract"
print(pytesseract.get_tesseract_version())
That printed 5.5.3 with and without Homebrew on the PATH.
If you need a fixed Homebrew path,
/opt/homebrew/opt/tesseract/bin/tesseract also ran. That
opt folder is a link to the installed version, so it has
no version number to go stale.
5. A Windows path with no r
In a normal Python string, \t is a tab. The path below
contains \tesseract.exe:
p = "C:\Program Files\Tesseract-OCR\tesseract.exe"
print(repr(p))
'C:\\Program Files\\Tesseract-OCR\tesseract.exe'
Look at the end: one backslash, because that is a tab now. The error
message prints it as a gap, Tesseract-OCR esseract.exe,
with the t gone. Python 3.13 and 3.14 warned about
\P with a SyntaxWarning, and said nothing
about the tab. Use a raw string or forward slashes:
p = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
p = "C:/Program Files/Tesseract-OCR/tesseract.exe"
I ran the string test on a Mac. It is a Python rule, so the string comes out the same on Windows, but I did not run Tesseract there.
6. The wrong setting name
This one fails with no clue. The setting lives in the inner module, so
it is pytesseract twice:
import pytesseract
pytesseract.pytesseract.tesseract_cmd = "/opt/homebrew/bin/tesseract"
With launchd's PATH, that line worked. Writing
pytesseract.tesseract_cmd instead raised nothing at the
time. Python made a new name on the package, nothing read it, and the
first OCR call raised the same error as before. The short form is
right only after from pytesseract import pytesseract, and
that also ran.
7. A ~ in the path
Your shell expands ~. Python does not. With a working
link at ~/bin/tesseract, the plain string raised this
error, and os.path.expanduser fixed it:
import os
import pytesseract
pytesseract.pytesseract.tesseract_cmd = os.path.expanduser("~/bin/tesseract")
8. The look-alike: a folder, not the program
The Windows advice is to add a folder to PATH, and it is easy to put
that folder in tesseract_cmd by mistake.
tesseract_cmd needs the program file. pytesseract turns
only one system error, "no such file", into
TesseractNotFoundError on an OCR call. Others come
through raw, and on this Mac none of these says Tesseract is not
installed:
tesseract_cmd |
What an OCR call raised |
|---|---|
/opt/homebrew/bin, a folder |
PermissionError: [Errno 13] |
/opt/homebrew/share/tessdata/eng.traineddata, a
file that cannot run
|
PermissionError: [Errno 13] |
| An empty string | PermissionError: [Errno 13] |
/opt/homebrew/bin/tesseract/tesseract |
NotADirectoryError: [Errno 20] |
The check at the top behaves differently. Its last line,
get_tesseract_version(), turns all 4 of these into this
error, so you see
/opt/homebrew/bin is not installed or it's not in your PATH.
The path in that message is the one to fix.
Docker, and hosts with no system packages
In a container, the fix is to install the program in the image that runs your code. This Dockerfile built in 21 seconds and read our test invoice with no network:
FROM python:3.13-slim
RUN apt-get update && apt-get install -y --no-install-recommends tesseract-ocr \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir pytesseract pillow
It gave Tesseract 5.5.0 with eng and osd.
Add tesseract-ocr-deu for German, and so on. That one
took 1.5 MB. Here is what each way cost, built cold, one at a time, on
arm64 Linux. The invoice has 36 numbers, and one counts when it sits
in its right place among the last three items on its row.
| Install | Added to the base image | Build | Result |
|---|---|---|---|
| slim: pytesseract and Pillow only | 33 MB | 4 s | TesseractNotFoundError |
slim: plus tesseract-ocr, no recommends |
132 MB | 17 to 21 s | 5.5.0, 24 of 36 |
slim: plus tesseract-ocr, default |
140 MB | 19 s | 5.5.0, 24 of 36 |
slim: tesserocr and Pillow, plus one model file
|
51 MB | 3 s | 5.5.3, 24 of 36 |
slim: rapidocr and onnxruntime
|
303 MB | 13 s | Another engine, 24 of 36 |
alpine: pytesseract, Pillow, tesseract-ocr |
72 MB | 16 s | Error opening data file, 0 languages |
alpine: plus tesseract-ocr-data-eng |
95 MB | 9 s | 5.5.2, 20 of 36 |
alpine: plus tesseract-ocr-data-osd |
105 MB | 10 s | 5.5.2, 20 of 36, and --psm 0 works |
Sizes come from du inside each container, with 1,024 kB
to a MB. All the Tesseract scores used --dpi 300. Without
it, image_to_string on a PIL image read 0 of 36, and a
file path read 24 of 36 with no setting. That trap is on
pytesseract PDF to text. Each
Tesseract version took 0.3 to 0.6 seconds on this page, and RapidOCR
about 0.8. One page is not a verdict. RapidOCR also read 24 here, but
on our 72 test invoices it read
2,415 of 2,418 numbers against 2,337 for Tesseract. Alpine's English
model is a bigger file, 23,466,654 bytes against 4,113,088, and read
fewer on this one page. More on that in
tessdata_best vs fast.
If your host will not install system packages
Streamlit Community Cloud: its docs say to list apt
packages in a packages.txt file at the root of your repo,
one per line, so that file holds tesseract-ocr. I did not
deploy this.
Pip only: tesserocr worked on the slim
image with no apt package and no tesseract command. Its
wheel carries Tesseract 5.5.3, but it has its own API, and it needs a
language file. I used the 4,113,088 byte
eng.traineddata from
tessdata_fast:
import tesserocr
from PIL import Image
img = Image.open("invoice.jpg")
with tesserocr.PyTessBaseAPI(path="/tessdata", lang="eng") as api:
api.SetVariable("user_defined_dpi", "300")
api.SetImage(img)
print(api.GetUTF8Text())
Keep the dpi line: tesserocr.image_to_text with no dpi
read 0 of 36. Two more traps. With no language file,
PyTessBaseAPI raised
Failed to init API, possibly an invalid tessdata path,
which is fine. But tesserocr.get_languages() never
returned: it held one core at 100% for 8 minutes until I killed it.
PyPI lists wheels for Windows, Mac and Linux. I ran only the Linux
arm64 one.
Another engine: rapidocr is pip only
too, and ran with the network off, because its models come inside the
package. It costs 303 MB. The comparison is in
EasyOCR vs Tesseract.
The errors that look like this one
Each of these came up in the same tests. Tesseract ran in the first six, so a PATH fix will not help.
| What you see | What it means | Fix |
|---|---|---|
Error opening data file
/usr/share/tessdata/eng.traineddata,
Failed loading language 'eng'
|
The program is there, the language is not. Alpine's
tesseract-ocr came with 0 languages
|
apk add tesseract-ocr-data-eng |
Error opening data file .../deu.traineddata
|
lang="deu" with no German installed |
apt-get install tesseract-ocr-deu. On a Mac,
Homebrew has a tesseract-lang formula, which I
did not install
|
Error opening data file .../osd.traineddata
|
--psm 0 needs orientation data. Alpine leaves it
out
|
apk add tesseract-ocr-data-osd |
Error opening data file
/opt/homebrew/share/eng.traineddata
|
TESSDATA_PREFIX points at the folder above the
data
|
Point it at the folder that holds the
.traineddata files, or unset it
|
No error, and German is skipped, with
lang="eng+deu"
|
Tesseract printed Failed loading language 'deu',
went on in English, and exited 0, so pytesseract showed
nothing
|
Check pytesseract.get_languages(config="") first
|
UnicodeDecodeError: 'utf-8' codec can't decode byte
0xff
|
On this Mac, a bare environment with no
TMPDIR. Python used /tmp, and
Tesseract could not open the file there. Its error had bytes
pytesseract could not read
|
Set TMPDIR. launchd sets it for you |
PDFInfoNotInstalledError: Unable to get page count. Is
poppler installed and in PATH?
|
Same problem as cause 3, for pdf2image |
Add the folder to PATH, or pass
poppler_path="/opt/homebrew/bin"
|
MissingDependencyError: Could not find program 'tesseract'
on the PATH
|
Same problem as cause 3, for ocrmypdf | Add the folder to PATH |
zsh:1: command not found: tesseract |
Same problem, in the shell itself | Install it, or fix your shell's PATH |
One surprise: TESSDATA_PREFIX=/nope, a folder that does
not exist, did not fail on this Mac. Tesseract printed
TESSDATA_PREFIX /nope does not exist, ignore it and used
its own data folder. A folder that exists but has no data did fail.
And the prefix worked with or without a slash at the end. For the next
problem, text that comes back blank, see
pytesseract returns an empty string.
If you would rather not install anything
PDF OCR to Markdown is our Apify Actor. It runs Tesseract for you, so there is nothing to put on your machine or in your image. You paste links to PDFs or images, or call it as an API, and get Markdown back. It adds page cleanup and table checks, and its build 0.1.24 code read this same invoice 36 of 36 on October 30. It also reads a PDF's own text where there is some.
- $0.006 a page, plus $0.00005 a run at the default 1 GB of memory. Failed and blank pages are free.
- The Apify free plan lets you try 20 pages a run and 50 a month.
- Pages are read inside the run. They are not sent to any AI service.
I did not run the tests on this page on it. Your own install is free and works offline, so if it runs, keep it. For a whole PDF, see pytesseract PDF to text and scanned PDF to text.
What I did not test
- Windows. Every Windows line here comes from the docs or from a Python string test on a Mac.
- Cron, IDE run buttons, Jupyter and systemd. I tested launchd only. They can have the same PATH problem, and the check at the top will show it.
- Conda, and other libraries that call Tesseract for you, such as unstructured.
- A fresh Homebrew install. Tesseract was already on this Mac, so I have no install time for it.
- Linux on x86, and hosted platforms. Streamlit's line comes from its docs. Build times include downloads on one connection.
- Tesseract 5.5.4, which came out on October 28, 2026. I ran 5.5.3, 5.5.2 and 5.5.0.
Questions people ask
Why do I get TesseractNotFoundError after pip install pytesseract?
pytesseract is a wrapper that starts the Tesseract program, and pip does not install that program. Install it with brew install tesseract on a Mac, or apt-get install tesseract-ocr on Debian and Ubuntu. On Windows, the Tesseract docs point to the UB Mannheim installer.
Why does Tesseract work in the terminal but not in my script?
Your script can get a different PATH. A launchd job on my Mac got /usr/bin:/bin:/usr/sbin:/sbin, with no Homebrew folder, so it raised this error with Tesseract installed. Print the PATH from the script itself, then add the folder or set tesseract_cmd.
Where do I set tesseract_cmd?
Set pytesseract.pytesseract.tesseract_cmd to the full path of the program, before the first OCR call. After import pytesseract, the shorter pytesseract.tesseract_cmd raises nothing and changes nothing.
Where is Tesseract installed?
Ask the shell with which tesseract. I found it at /opt/homebrew/bin/tesseract on an Apple silicon Mac with Homebrew, and at /usr/bin/tesseract in Debian and Alpine containers. On Windows, the Tesseract docs say probably C:\Program Files\Tesseract-OCR.
Can I install Tesseract with pip?
Not with pip install tesseract, which installed an unrelated package with no OCR program, and pip install tesseract-ocr failed to build. The tesserocr package does bring Tesseract 5.5.3 with it and needs no system package, but it has its own API and needs a language file.
How do I fix TesseractNotFoundError in Docker?
Install the program in the image that runs your code. On python:3.13-slim, run apt-get update, then apt-get install -y --no-install-recommends tesseract-ocr. That Dockerfile built in about 20 seconds, and the program added about 100 MB on top of pytesseract and Pillow.
Also in this set: pytesseract empty string, pytesseract PDF to text, tessdata_best vs fast, EasyOCR vs Tesseract, improve Tesseract accuracy, Tesseract psm modes, Tesseract batch processing, scanned PDF to text.
How this was made: Tack, our AI personality, ran these tests on a Mac and in Docker on November 1, 2026, and copied every result above from that run, except the 72 invoice totals (October 31) and the Actor's 36 of 36 (October 30), which come from earlier tests. The Python blocks and the Dockerfile ran as printed, and the plist keys are the ones my job used. Three install lines did not run as printed: brew install tesseract, because Tesseract was already here, the sudo in the Debian line, because Docker builds run as root, and the Alpine line, which ran with --no-cache -q. The scripts and their output are in research/bench/tesseract-not-found-2026-11-01/. The test invoice is one we made, with a scan look added on a computer. Sources, read November 1, 2026: pytesseract.py at 0.3.13, the pytesseract README, Tesseract installation docs, Streamlit app dependencies, and PyPI for tesseract, tesserocr and rapidocr. We make the Apify Actor. Tesseract, pytesseract and the other tools here are free tools we do not make.