opendatalab/MinerU · error · HTTPException

Unsupported file type: {file_suffix}

Error message

Unsupported file type: {file_suffix}

What it means

HTTP 400 raised by the fast_api upload endpoint after the uploaded bytes were written to disk: the file's suffix (from filename and/or content sniffing via guess_suffix_by_path) is not in SUPPORTED_UPLOAD_SUFFIXES, which is pdf_suffixes + image_suffixes + office_suffixes = pdf, png, jpeg, jp2, webp, gif, bmp, jpg, tiff, docx, pptx, xlsx. The partially stored file is deleted before the exception is raised. Note guess_suffix_by_path can return 'unknown' when the content does not match any known magic bytes, so even a named .pdf can be rejected if it is not actually a PDF.

Source

Thrown at mineru/cli/fast_api.py:767

    uploads: list[StoredUpload] = []

    for upload in files:
        original_name = upload.filename or f"upload-{uuid.uuid4()}"
        filename = normalize_upload_filename(original_name)
        normalized_stem = normalize_task_stem(Path(filename).stem)
        destination = build_upload_destination(upload_dir, filename)
        try:
            with open(destination, "wb") as handle:
                while True:
                    chunk = await upload.read(1 << 20)
                    if not chunk:
                        break
                    handle.write(chunk)

            file_suffix = guess_suffix_by_path(destination)
            if file_suffix not in SUPPORTED_UPLOAD_SUFFIXES:
                cleanup_file(str(destination))
                raise HTTPException(
                    status_code=400,
                    detail=f"Unsupported file type: {file_suffix}",
                )

            uploads.append(
                StoredUpload(
                    original_name=original_name,
                    stem=normalized_stem,
                    path=str(destination),
                )
            )
        except Exception:
            cleanup_file(str(destination))
            raise
        finally:
            await upload.close()

    normalized_stems, renamed_stems = uniquify_task_stems(

View on GitHub (pinned to 4fe4bde114)

Solutions

  1. Re-check the uploaded file type: only pdf, png, jpeg/jpg, jp2, webp, gif, bmp, tiff, docx, pptx, xlsx are accepted.
  2. Convert legacy Office files (.doc/.ppt/.xls) to their x-variants before upload.
  3. If the extension looks right, verify the file opens locally and is not corrupted/truncated; compare magic bytes (e.g. %PDF- for pdf).
  4. Client-side, read the 400 detail in the response body — it names the detected suffix, which tells you whether it is an extension problem or 'unknown' content.

Example fix

# before
files = {'files': open('report.doc', 'rb')}
requests.post('http://127.0.0.1:8000/file_parse', files=files)  # 400 Unsupported file type: doc

# after
# convert first: soffice --headless --convert-to docx report.doc
files = {'files': open('report.docx', 'rb')}
requests.post('http://127.0.0.1:8000/file_parse', files=files)
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {'pdf', 'png', 'jpeg', 'jpg', 'jp2', 'webp', 'gif', 'bmp', 'tiff', 'docx', 'pptx', 'xlsx'}

def can_upload(name: str) -> bool:
    return name.rsplit('.', 1)[-1].lower() in ALLOWED if '.' in name else False

Type guard

def is_supported_upload(filename: str) -> bool:
    return can_upload(filename)

Try / catch

# requests
r = requests.post(url, files=files)
if r.status_code == 400 and 'Unsupported file type' in r.text:
    detected = r.json().get('detail', '').rsplit(':', 1)[-1].strip()
    if detected == 'unknown':
        raise RuntimeError('File content unrecognizable — corrupted upload?')
    raise ValueError(f'Convert {detected} files before uploading')

Prevention

When it happens

Trigger: POST /file_parse or the async parse endpoint with a .doc/.ppt/.xls, .txt, .md, .html, or any other unsupported extension; uploading a file whose extension is fine but whose bytes are not recognizable (renamed file, corrupted upload, truncated body) so suffix detection returns 'unknown'; double extension like file.pdf.exe.

Common situations: Assuming legacy Office formats are accepted because docx/pptx/xlsx are; content sniffing disagreeing with the filename after a bad proxy/encoding step; tests posting dummy bytes with a .pdf name.

Related errors


AI-assisted analysis of opendatalab/MinerU@4fe4bde114 (2026-08-14). Data as JSON: /api/errors/4ad901da65ad3272. Report an issue: GitHub.