opendatalab/MinerU · error · ValueError
Legacy binary PPT files are not supported; convert the file
Error message
Legacy binary PPT files are not supported; convert the file to PPTX before parsing.
What it means
normalize_pptx_package rejects legacy binary PowerPoint files by magic number (the OLE2 compound-document signature, D0 CF 11 E0 ...). python-pptx can only read the OOXML zip format (.pptx), so .ppt files from PowerPoint 97-2003 fail immediately with a clear message instead of a confusing downstream parse error.
Source
Thrown at mineru/model/pptx/package_normalizer.py:92
(
b"http://purl.oclc.org/ooxml/officeDocument/docPropsVTypes",
b"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
),
(
b"http://purl.oclc.org/ooxml/officeDocument/oleObject",
b"http://schemas.openxmlformats.org/officeDocument/2006/oleObject",
),
)
KNOWN_NAMESPACE_DECLARATIONS = {
b"w": f'xmlns:w="{WORDPROCESSINGML_NS}"'.encode("utf-8"),
}
def normalize_pptx_package(file_bytes: bytes) -> bytes:
"""在进入 python-pptx 前修复常见包级兼容问题,避免修复逻辑散落到形状解析阶段。"""
if file_bytes.startswith(LEGACY_PPT_MAGIC):
raise ValueError(
"Legacy binary PPT files are not supported; convert the file to PPTX before parsing."
)
try:
with ZipFile(BytesIO(file_bytes)) as source:
loaded_members: list[tuple[ZipInfo, bytes]] = []
rewritten_members: list[tuple[ZipInfo, bytes]] = []
skipped_members: set[str] = set()
changed = False
for info in source.infolist():
member_data = _read_member_best_effort(source, info)
if member_data is None:
skipped_members.add(info.filename)
changed = True
continue
loaded_members.append((info, member_data))
View on GitHub (pinned to 4fe4bde114)
Solutions
- Convert the file to real PPTX with LibreOffice: soffice --headless --convert-to pptx file.ppt.
- Detect the format upstream by magic bytes, not extension, and route legacy files to a converter.
- Re-export from the source application in Office 2007+ format.
Example fix
# before
result = parse_pptx(open('deck.ppt','rb').read())
# after
subprocess.run(['soffice','--headless','--convert-to','pptx','deck.ppt'])
result = parse_pptx(open('deck.pptx','rb').read()) Defensive patterns
Strategy: validation
Validate before calling
LEGACY = bytes.fromhex('d0cf11e0a1b11ae1')
def is_legacy_ppt(data: bytes) -> bool:
return data[:8] == LEGACY Try / catch
try:
normalized = normalize_pptx_package(data)
except ValueError as e:
if 'Legacy binary PPT' in str(e):
raise ValueError('convert with: soffice --headless --convert-to pptx <file>') from e
raise Prevention
- Sniff magic bytes at the upload boundary; never trust the extension.
- Auto-convert legacy Office formats in an ingest queue before parsing.
- Document accepted formats (OOXML only) in the API contract.
When it happens
Trigger: Feeding a .ppt (or any OLE2 container like some .doc/.xls) file to the PPTX parsing pipeline; often happens because the file was renamed to .pptx without conversion.
Common situations: Users renaming instead of converting, scanned/exported documents saved in compatibility mode, or content-disposition pipelines that route by extension while the bytes are legacy format.
Related errors
- Invalid PPTX package: file is not a ZIP archive.
- Unknown file suffix: {file_suffix}
- Unsupported office suffix: {file_suffix}
- Unsupported file type: {file_suffix}
- Invalid XLSX package: file is not a ZIP archive.
AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14).
Data as JSON: /api/errors/f5410f9d13208609.
Report an issue: GitHub.