## TL;DR
Tesseract's 'Tesseract couldn't load any languages' in Docker means TESSDATA_PREFIX points at a directory that does not exist or has no traineddata files in the container. The tesseract binary is installed but its language data is not where the environment variable says it is. Find the real tessdata directory inside the image, set TESSDATA_PREFIX to it in the Dockerfile, and verify with tesseract --list-langs. Bake the check into the image build so the next deploy cannot regress.

## The query
```text
tesseract 'Tesseract couldn't load any languages'  -  the tessdata path is wrong in Docker
```

## Use this when
- Tesseract reports 'couldn't load any languages' inside Docker but works on the host
- A fresh image broke a previously working OCR pipeline
- You installed tesseract-ocr but not tesseract-ocr-eng (or the data package)

## Not for
- 'Error opening data file ./tessdata/eng.traineddata' with a correct TESSDATA_PREFIX - that is a missing language pack, not a wrong path
- Tesseract failing on specific images while listing languages fine - an image-quality problem
- Permission errors reading the tessdata directory - a filesystem problem, not a path problem

## Steps
### 1. Inspect the variable and the directory inside the container
Check what TESSDATA_PREFIX is set to and whether that directory exists and contains traineddata files. The usual failure: the variable points at the host's path, or the data package was never installed.
```bash
docker exec [CONTAINER] sh -c 'echo "PREFIX=$TESSDATA_PREFIX"; ls "$TESSDATA_PREFIX" 2>&1 | head'
```
Expected output: either a missing directory or an empty one - the concrete misconfiguration, not a guess.

### 2. Find the real tessdata directory
Locate where the traineddata files actually live in the image. Package installs put them in a versioned path that rarely matches a hardcoded prefix.
```bash
docker exec [CONTAINER] sh -c 'find /usr -name "eng.traineddata" 2>/dev/null; dpkg -L tesseract-ocr 2>/dev/null | grep tessdata | head'
```
Expected output: the real path, e.g. a versioned directory under /usr/share/tesseract-ocr.

### 3. Set TESSDATA_PREFIX correctly in the Dockerfile
Install both the binary and the language data, then set the prefix to the real directory at build time. Installing tesseract-ocr without tesseract-ocr-eng (or your languages) is the classic incomplete install.
```dockerfile
RUN apt-get update && apt-get install -y --no-install-recommends tesseract-ocr tesseract-ocr-eng && rm -rf /var/lib/apt/lists/*
ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/5/tessdata/
```
Expected output: rebuilt image where the prefix matches the installed data location.

### 4. Verify with --list-langs in the built image
Run the language list in a container from the final image - the definitive check that the data resolves.
```bash
docker run --rm [IMAGE] tesseract --list-langs
```
Expected output: a list including eng (and any other installed languages), proving OCR will find its data.

## Tool compatibility
Tesseract OCR 4.x/5.x; Docker with Debian/Ubuntu-based images (adjust package names and paths for other bases). The TESSDATA_PREFIX mechanism is the same on bare metal.

## Variant phrasings
- tesseract Tesseract couldn't load any languages Docker
- tesseract tessdata path wrong in Docker TESSDATA_PREFIX
- tesseract --list-langs empty Docker container
- tesseract-ocr installed but no languages Docker

## Why it happens
Tesseract splits into a binary and language data files, and locates the data via TESSDATA_PREFIX with a compiled-in fallback. Docker images frequently install the binary package without the language-data package, or copy a TESSDATA_PREFIX from a blog post that matches no real path in the image. The binary then starts fine - it only discovers the data is missing when it tries to load a language, producing this error instead of a startup failure.

## Edge cases / pitfalls
- TESSDATA_PREFIX must end with a trailing slash on some builds; include it to be safe.
- Multi-stage builds can install tessdata in the build stage and drop it in the runtime stage - verify in the final image, not the builder.
- Custom traineddata files go in the same directory; confirm they are listed by --list-langs after adding.
- Some minimal images set TESSDATA_PREFIX globally to a wrong value - your Dockerfile ENV overrides it, but check for conflicts.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_APs8NEIMFrOaxq5LsbTTAA
