docling-project/docling · error · ValueError
Invalid filename: contains null byte.
Error message
Invalid filename: contains null byte.
What it means
Filenames handed to the Tesseract CLI (e.g. input images and output bases) are sanitized before subprocess invocation. A filename containing a NUL byte raises this ValueError, mirroring the path and command sanitizers, since NUL bytes cannot occur in valid filenames and signal malformed or injected input.
Source
Thrown at docling/models/stages/ocr/tesseract_ocr_cli_model.py:132
@staticmethod
def _sanitize_cmd(cmd: str) -> str:
"""Validate and sanitize the Tesseract executable name/path to prevent injection.
Rejects values containing null bytes.
"""
if "\x00" in cmd:
raise ValueError("Invalid Tesseract command: contains null byte.")
return cmd
@staticmethod
def _sanitize_filename(filename: str) -> str:
"""Validate and sanitize a filename passed to the Tesseract CLI.
Rejects paths containing null bytes and resolves to an absolute path.
"""
if "\x00" in filename:
raise ValueError("Invalid filename: contains null byte.")
return str(Path(filename).resolve())
def _get_name_and_version(self) -> Tuple[str, str]:
if self._name is not None and self._version is not None:
return self._name, self._version # type: ignore
cmd = [self._safe_tesseract_cmd, "--version"]
proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=False)
stdout, stderr = proc.communicate()
proc.wait()
# HACK: Windows versions of Tesseract output the version to stdout, Linux versions
# to stderr, so check both.
version_line = (
(stdout.decode("utf8").strip() or stderr.decode("utf8").strip())
.split("\n")[0]View on GitHub (pinned to 61d76f1ff3)
Solutions
- Clean or drop the offending path; strip control characters from file lists before processing.
- Validate external path sources (manifests, uploads) with a null-byte check up front.
- Log repr(path) for failed batches to identify the corrupted entry quickly.
Example fix
# before paths = ["page1.png\x00", "page2.png"] # after paths = [p for p in raw_paths if "\x00" not in p]
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def safe_filenames(paths: list[str]) -> list[str]:
bad = [p for p in paths if "\x00" in p]
if bad:
raise ValueError(f"filenames contain NUL bytes: {bad!r}")
return [str(Path(p).resolve()) for p in paths] Type guard
def is_nul_free_filename(p: str) -> bool:
return bool(p) and "\x00" not in p Try / catch
try:
model.run_batch(files)
except ValueError as e:
if "Invalid filename" in str(e):
files = [f for f in files if is_nul_free_filename(f)]
model.run_batch(files)
else:
raise Prevention
- Validate externally sourced filenames (uploads, manifests) before batch processing.
- Decode path data strictly; treat undecodable/control-char entries as corrupt.
- Skip-and-log bad entries rather than aborting whole batches when appropriate.
When it happens
Trigger: Any flow that passes a filename containing \x00 to the CLI-based Tesseract model — e.g. processing a list of files where one path came from binary or corrupted metadata.
Common situations: Batch processing paths read from untrusted manifests, archives with malformed entry names, or strings decoded from binary blobs.
Related errors
- Invalid Tesseract language identifier: {lang!r}. Language id
- Invalid Tesseract data path: contains null byte.
- Invalid Tesseract command: contains null byte.
- invalid tesseract document orientation {orientation}, expect
- Archive exceeds maximum member count limit of {self.options.
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/0a053c79ababc19b.
Report an issue: GitHub.