microsoft/markitdown · error · RuntimeError

Failed to verify ExifTool version.

Error message

Failed to verify ExifTool version.

What it means

Before extracting metadata, MarkItDown runs `exiftool -ver` with check=True and parses the output with _parse_version. If the subprocess exits non-zero (exiftool missing, broken, or unusable) or the version string cannot be parsed into numeric components (raises ValueError), this generic RuntimeError wraps the underlying cause. It means exiftool exists on PATH per the earlier lookup but cannot be executed or version-queried successfully.

Source

Thrown at packages/markitdown/src/markitdown/converters/_exiftool.py:36

        return {}

    # Verify exiftool version
    try:
        version_output = subprocess.run(
            [exiftool_path, "-ver"],
            capture_output=True,
            text=True,
            check=True,
        ).stdout.strip()
        version = _parse_version(version_output)
        min_version = (12, 24)
        if version < min_version:
            raise RuntimeError(
                f"ExifTool version {version_output} is vulnerable to CVE-2021-22204. "
                "Please upgrade to version 12.24 or later."
            )
    except (subprocess.CalledProcessError, ValueError) as e:
        raise RuntimeError("Failed to verify ExifTool version.") from e

    # Run exiftool
    cur_pos = file_stream.tell()
    try:
        output = subprocess.run(
            [exiftool_path, "-json", "-"],
            input=file_stream.read(),
            capture_output=True,
            text=False,
        ).stdout

        return json.loads(
            output.decode(locale.getpreferredencoding(False)),
        )[0]
    finally:
        file_stream.seek(cur_pos)

View on GitHub (pinned to fd239d5d2b)

Solutions

  1. Run `exiftool -ver` in the same shell/environment where your code runs and inspect the error; fix whatever it reports
  2. Ensure a real, executable exiftool >= 12.24 is first on PATH (test with `which -a exiftool`)
  3. On Windows use the standalone exiftool.exe; make sure it is named exiftool(-k).exe renamed to exiftool.exe and executable
  4. If the environment cannot run subprocesses, install exiftool through a package manager that ships a self-contained binary (e.g. static build)

Example fix

# before: PATH contains a broken wrapper
$ exiftool -ver
/usr/bin/env: 'perl': No such file or directory

# after: install perl or a self-contained build
$ apt-get install -y perl libimage-exiftool-perl
$ exiftool -ver
12.76
Defensive patterns

Strategy: validation

Validate before calling

import shutil, subprocess

def exiftool_works() -> bool:
    path = shutil.which("exiftool")
    if not path:
        return False
    try:
        subprocess.run([path, "-ver"], capture_output=True, check=True, timeout=10)
        return True
    except Exception:
        return False

Try / catch

try:
    result = MarkItDown().convert("photo.jpg")
except RuntimeError as e:
    if "Failed to verify ExifTool version" in str(e):
        logger.error("exiftool present but not executable/version-unparseable: %s", e)
        raise

Prevention

When it happens

Trigger: exiftool binary on PATH is corrupt, not executable, or a wrapper script that fails; platform-specific execution failures (e.g. Windows requiring perl, or the standalone exiftool.exe renamed); exiftool -ver printing unexpected text (e.g. warnings mixed in, or a non-numeric version) causing _parse_version to raise ValueError; architecture mismatch (x86 binary on ARM).

Common situations: The exiftool executable found via shutil.which is a stub or broken symlink; exiftool needs a missing shared library / perl module; PATH resolves to the wrong binary (e.g. a directory named 'exiftool' shadowing the tool); restricted environments (noexec mounts, sandboxed CI) preventing subprocess execution.

Related errors


AI-assisted analysis of microsoft/markitdown@fd239d5d2b (2026-08-14). Data as JSON: /api/errors/9a2746db01252577. Report an issue: GitHub.