openpyxl InvalidFileException: does not support file format (tested)

openpyxl.utils.exceptions.InvalidFileException: openpyxl does not support .csv file format (or the old .xls file format) comes from the file extension: openpyxl only opens .xlsx, .xlsm, .xltx and .xltm. Read CSVs with read_csv and .xls files with xlrd.

1. Four files, four different errors

from openpyxl import load_workbook
open("/tmp/data.csv", "w").write("a,b\n1,2\n")
open("/tmp/old.xls", "wb").write(bytes.fromhex("d0cf11e0a1b11ae1") + b"\0" * 504)  # OLE2 header, like a real .xls
open("/tmp/report.xlsx", "w").write("<html><body>Session expired</body></html>")
for p in ["/tmp/data.csv", "/tmp/old.xls", "/tmp/report.xlsx", "/tmp/nope.xlsx"]:
    try:
        load_workbook(p)
    except Exception as e:
        print(f"{p}: {type(e).__module__}.{type(e).__name__}: {e}")

Output:

/tmp/data.csv: openpyxl.utils.exceptions.InvalidFileException: openpyxl does not support .csv file format, please check you can open it with Excel first. Supported formats are: .xlsx,.xlsm,.xltx,.xltm
/tmp/old.xls: openpyxl.utils.exceptions.InvalidFileException: openpyxl does not support the old .xls file format, please use xlrd to read this file, or convert it to the more recent .xlsx file format.
/tmp/report.xlsx: zipfile.BadZipFile: File is not a zip file
/tmp/nope.xlsx: builtins.FileNotFoundError: [Errno 2] No such file or directory: '/tmp/nope.xlsx'

load_workbook() first checks the extension. .csv and any other non-Excel extension raise InvalidFileException with the list of supported formats (.xlsx, .xlsm, .xltx, .xltm). A .xls gets its own message: openpyxl never reads the old binary Excel format. A file named .xlsx that is not really one (here an HTML page saved by a download) gets past the extension check and fails as zipfile.BadZipFile, because a real .xlsx is a zip archive.

2. Read each format with the right tool

import pandas as pd
open("/tmp/data.csv", "w").write("a,b\n1,2\n")
try:
    pd.read_excel("/tmp/data.csv")
except Exception as e:
    print(f"read_excel(.csv): {type(e).__name__}: {e}")
print(pd.read_csv("/tmp/data.csv").to_dict("records"))
with open("/tmp/old.xls", "rb") as f: head = f.read(8)
print("old.xls first bytes:", head.hex(), "-> OLE2 (real .xls)" if head == bytes.fromhex("d0cf11e0a1b11ae1") else "")
with open("/tmp/report.xlsx", "rb") as f: print("report.xlsx first bytes:", f.read(15))

Output:

read_excel(.csv): ValueError: Excel file format cannot be determined, you must specify an engine manually.
[{'a': 1, 'b': 2}]
old.xls first bytes: d0cf11e0a1b11ae1 -> OLE2 (real .xls)
report.xlsx first bytes: b'<html><body>Ses'

For a CSV, use pd.read_csv() or the csv module; pd.read_excel() on a .csv fails with ValueError: Excel file format cannot be determined. For a real .xls (first bytes d0cf11e0a1b11ae1), use pd.read_excel(path, engine="xlrd") with pip install xlrd, or convert it to .xlsx once in Excel or LibreOffice. If the first bytes are <html, you downloaded an error or login page, not a spreadsheet: fix the download.

Checklist

Related: BadZipFile: File is not a zip file · openpyxl IllegalCharacterError · Missing optional dependency openpyxl.

Frequently asked questions

Why does openpyxl say it does not support the old .xls file format?

openpyxl only reads the zip-based formats (.xlsx, .xlsm, .xltx, .xltm). Use xlrd (pd.read_excel(path, engine='xlrd')) or convert the file to .xlsx.

Can openpyxl open a CSV file?

No. load_workbook raises InvalidFileException for .csv. Use pandas.read_csv or the csv module.

Why do I get BadZipFile instead of InvalidFileException?

The file has an .xlsx extension but is not a zip archive: usually an HTML page from a failed download or a renamed CSV/XLS.

Written with AI assistance. Measured on 2026-10-23 with openpyxl 3.1.5, pandas 3.1.0 and Python 3.15.1 (python:3-slim in Docker). Each block was run verbatim and the output pasted unedited. PlainTables is our extension; Python and openpyxl are free.