docling-project/docling · error · ImportError

The 'python-oxmsg' package is required to process Outlook .m

Error message

The 'python-oxmsg' package is required to process Outlook .msg files. Install it with `pip install 'docling-slim[format-email]'`.

What it means

When the input starts with the Outlook .msg magic bytes, the backend projects it onto RFC 822 via python-oxmsg; if that optional package is missing, _msg_to_rfc822_bytes raises ImportError with the chained original error. mail-parser alone is not enough for .msg files — both packages come with the format-email extra.

Source

Thrown at docling/backend/email_backend.py:129

        raise TypeError(f"Unsupported input type: {type(self.path_or_stream)}")

    @staticmethod
    def _header_safe(value: str) -> str:
        # Email header values must be single-line; collapse CR/LF to spaces so a
        # crafted .msg cannot inject headers and EmailMessage does not reject it.
        return value.replace("\r", " ").replace("\n", " ").strip()

    @staticmethod
    def _msg_to_rfc822_bytes(data: bytes) -> bytes:
        """Project an Outlook ``.msg`` (OLE2/CFB) onto RFC 822 bytes.

        python-oxmsg reads the MAPI message; we assemble a standard
        ``email.message.EmailMessage`` from it so the ``.msg`` path shares the
        exact body, HTML, address, and attachment handling used for ``.eml``
        input.
        """
        if not _OXMSG_AVAILABLE:
            raise ImportError(_MSG_INSTALL_HINT) from _OXMSG_IMPORT_ERROR

        message = OxMsgMessage.load(data)
        email_message = EmailMessage()

        if message.subject:
            email_message["Subject"] = EmailDocumentBackend._header_safe(
                message.subject
            )
        if message.sender:
            email_message["From"] = EmailDocumentBackend._header_safe(message.sender)

        # Preserve the To/Cc/Bcc split from the recipient rows so downstream
        # rendering (which shows only "To") matches the .eml behavior.
        grouped: dict[str, list[str]] = {}
        for recipient in message.recipients:
            formatted = formataddr(
                (recipient.name or "", recipient.email_address or "")
            )

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Install the extra: pip install 'docling-slim[format-email]' (brings both mailparser and python-oxmsg)
  2. Or add python-oxmsg explicitly to the environment
  3. Regenerate the lockfile after upgrading Docling so new optional deps are captured

Example fix

# before
pip install mailparser  # .eml works, .msg raises ImportError

# after
pip install 'docling-slim[format-email]'  # includes mailparser + python-oxmsg
Defensive patterns

Strategy: validation

Validate before calling

try:
    import oxmsg  # python-oxmsg
except ImportError:
    raise RuntimeError(".msg support needs: pip install 'docling-slim[format-email]'")

Try / catch

try:
    result = converter.convert(msg_path)
except ImportError as exc:
    if 'python-oxmsg' in str(exc):
        install_or_skip('docling-slim[format-email]')
    raise

Prevention

When it happens

Trigger: Converting an Outlook .msg file (detected by OLE2/CFB magic bytes) in an environment that has mailparser installed but not python-oxmsg, e.g. only `pip install mailparser` was done manually.

Common situations: Manually installing the mail dependencies instead of using the extra; environments frozen before .msg support was added; partial dependency lock files.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/4ac0f0a1a8daee38. Report an issue: GitHub.