Fix "Filesize would require ZIP64 extensions" (LargeZipFile) in XlsxWriter
A nightly export that has run for months suddenly fails at the very end — after minutes of writing — with:
xlsxwriter.exceptions.FileSizeError: Filesize would require ZIP64 extensions. Use workbook.use_zip64().
Older XlsxWriter versions, and code that catches the lower-level exception, show zipfile.LargeZipFile: File size too large instead. The message mentions file size, but the finished .xlsx may be only a few hundred megabytes. What crossed the limit is one XML part inside the package, before compression. This page explains the limit, shows how to predict when an export will hit it, and covers the one-line fix and the cases where the better fix is a smaller workbook. It belongs to Troubleshooting Common Python Excel Errors.
Prerequisites
pip install xlsxwriter pandas
Reproducing the error for real means writing more than two gigabytes of XML, which takes minutes and a lot of disk. The examples below lower Python's zipfile threshold for the duration of a test, so the same code path raises the same exception on a small workbook.
Step 1 — Understand what the limit applies to
An .xlsx file is a ZIP archive, and each worksheet is one member of it: xl/worksheets/sheet1.xml. The original ZIP format records sizes in 32-bit fields; members larger than that need the ZIP64 extension. Python's zipfile refuses to write ZIP64 unless the caller allows it, and its threshold is zipfile.ZIP64_LIMIT:
import zipfile
print(f"{zipfile.ZIP64_LIMIT:,} bytes = {zipfile.ZIP64_LIMIT / 2**30:.2f} GiB")
The limit is 2,147,483,647 bytes — 2 GiB — per member, uncompressed. XlsxWriter writes each sheet's XML to a temporary file first and adds it to the archive when you call close(), which is why the error appears at the very end. Sheet XML compresses about four to one, so a workbook can fail with a 2 GiB sheet part while the final .xlsx would have been around 500 MB.
Step 2 — Reproduce it on a small workbook
import xlsxwriter
from xlsxwriter.exceptions import FileSizeError
def write_rows(path, rows, **options):
wb = xlsxwriter.Workbook(path, options)
ws = wb.add_worksheet()
for r in range(rows):
ws.write_row(r, 0, [r, r * 1.5, f"item {r % 50}"])
wb.close()
real_limit = zipfile.ZIP64_LIMIT
zipfile.ZIP64_LIMIT = 50_000 # pretend the limit is 50 KB
try:
write_rows("export.xlsx", 5_000)
except FileSizeError as exc:
print("FileSizeError:", exc)
print("caused by:", type(exc.__context__).__name__)
finally:
zipfile.ZIP64_LIMIT = real_limit
The sheet's XML for 5,000 rows is well over 50 KB, so close() raises exactly the production error, with zipfile.LargeZipFile as the underlying cause. Restoring the real limit in finally matters — the constant is global for the whole process.
Step 3 — Turn on ZIP64
XlsxWriter allows ZIP64 through a constructor option or a method; either must be set before close():
zipfile.ZIP64_LIMIT = 50_000
try:
write_rows("export_zip64.xlsx", 5_000, use_zip64=True)
print("written with ZIP64")
finally:
zipfile.ZIP64_LIMIT = real_limit
from openpyxl import load_workbook
print("rows read back:", load_workbook("export_zip64.xlsx", read_only=True).active.max_row)
Workbook(path, {"use_zip64": True}) and calling workbook.use_zip64() after creating the workbook are equivalent. The output is a valid ZIP64 package; current Excel versions, LibreOffice, openpyxl and pandas read it. XlsxWriter keeps ZIP64 off by default because some older ZIP readers do not understand the extension, so enable it for the exports that need it rather than everywhere, and open one such file in the oldest Excel your recipients use before relying on it.
From pandas, pass the option through engine_kwargs:
import pandas as pd
df = pd.DataFrame({"id": range(5_000), "value": [i * 1.5 for i in range(5_000)]})
zipfile.ZIP64_LIMIT = 50_000
try:
with pd.ExcelWriter("pandas_zip64.xlsx", engine="xlsxwriter",
engine_kwargs={"options": {"use_zip64": True}}) as xw:
df.to_excel(xw, index=False)
print("pandas export written")
finally:
zipfile.ZIP64_LIMIT = real_limit
Step 4 — Predict when an export will hit the limit
Measure how many bytes of XML one cell of your data produces, then extrapolate. A sample of 20,000 rows is enough:
import random
random.seed(0)
sample_rows, cols = 20_000, 20
wb = xlsxwriter.Workbook("sample.xlsx", {"constant_memory": True})
ws = wb.add_worksheet()
for r in range(sample_rows):
ws.write_row(r, 0, [random.random() * 10_000 for _ in range(15)] + [f"cat{random.randint(1, 50)}" for _ in range(5)])
wb.close()
part = zipfile.ZipFile("sample.xlsx").getinfo("xl/worksheets/sheet1.xml")
per_cell = part.file_size / (sample_rows * cols)
print(f"{per_cell:.1f} bytes per cell; compressed {part.file_size / part.compress_size:.1f}:1")
print(f"cells per sheet before the limit: {real_limit / per_cell:,.0f}")
print(f"columns that fit in 1,048,576 rows: {real_limit / per_cell / 1_048_576:.0f}")
With this mix of decimals and short text, each cell costs about 45 bytes of XML, so a sheet reaches 2 GiB at roughly 48 million cells — a full-height sheet of 1,048,576 rows with around 45 columns. Long text, many-digit floats and cell formats push the number per cell up; small integers push it down. Run the estimate on a sample of your real data before the export grows into the limit.
Step 5 — Consider a smaller workbook instead
Turning on ZIP64 makes the file writable; it does not make it usable. A worksheet with tens of millions of cells opens slowly, strains Excel's memory and is close to the sheet's row limit anyway. Often the better fix is structural:
- Split across sheets — one sheet per month or region keeps each part well under the limit; see Create a Sheet for Each Group in a DataFrame.
- Split across files — one workbook per period or customer, as in Split a Large Excel File into Files of N Rows.
- Summarise — ship the pivot, not the raw rows, and put the detail in Parquet or a database for whoever needs it.
- Change format — machine consumers are better served by CSV or Parquet, compared in Excel vs CSV vs Parquet for Python Data Pipelines.
Step 6 — Decide before writing, not after
The worst property of this error is its timing: it arrives after the whole export has been generated. A pre-flight check using the bytes-per-cell estimate from Step 4 lets the job choose ZIP64 — or a split — before it starts:
def needs_zip64(n_rows, n_cols, bytes_per_cell=per_cell, margin=1.25):
return n_rows * n_cols * bytes_per_cell * margin > real_limit
for rows, cols in [(500_000, 20), (1_048_576, 30), (1_048_576, 60)]:
print(f"{rows:>9,} x {cols:>2} -> use_zip64={needs_zip64(rows, cols)}")
The 25% margin covers the variation between your sample and the full data. Feeding the result straight into the workbook options — xlsxwriter.Workbook(path, {"use_zip64": needs_zip64(len(df), df.shape[1])}) — keeps small exports on the most compatible format and turns ZIP64 on only for the large ones. Log the decision, so that a recipient who reports a problem opening the file can be matched to the exports that used the extension.
Performance notes
Exports of this size are where XlsxWriter's constant_memory option earns its keep: rows are flushed to the temporary file as they are written, so memory stays flat instead of growing with the sheet. It requires writing rows in order, top to bottom. The ZIP64 option itself costs nothing measurable. The time goes into generating and compressing gigabytes of XML — expect several minutes for a sheet near the limit — which is one more argument for splitting very large exports or moving them to Parquet.
Common pitfalls
- Judging by the final file size. The limit is on the uncompressed sheet XML, roughly four times the size of the compressed workbook.
- Setting the option too late.
use_zip64must be set beforeclose(), and for pandas before the writer closes. - Leaving a patched limit in place. If you lower
zipfile.ZIP64_LIMITin a test, restore it infinally. - Shared strings. Huge amounts of unique text can push
sharedStrings.xmlover the limit instead of the sheet; the same option fixes it. - Hitting the row limit next. 1,048,576 rows per sheet still applies; see Fix "This sheet is too large" Error.
Conclusion
FileSizeError: Filesize would require ZIP64 extensions (or zipfile.LargeZipFile) means one XML part of the workbook exceeds 2 GiB uncompressed — typically a sheet with tens of millions of cells. Enable ZIP64 with Workbook(path, {"use_zip64": True}) or, from pandas, engine_kwargs={"options": {"use_zip64": True}}. Estimate bytes per cell on a sample to see the limit coming, and when people will open the file, prefer splitting or summarising over a single enormous sheet.
Frequently asked questions
What does "Filesize would require ZIP64 extensions" mean in XlsxWriter? One part of the .xlsx package, usually a worksheet's XML, is larger than 2 GiB before compression. Python's zipfile needs the ZIP64 extension for that, and XlsxWriter only allows it when you enable use_zip64.
How do I enable ZIP64 in XlsxWriter? Pass {"use_zip64": True} as the options argument of xlsxwriter.Workbook, or call workbook.use_zip64() before closing the workbook.
How do I fix LargeZipFile when writing Excel with pandas? Use the xlsxwriter engine and pass engine_kwargs={"options": {"use_zip64": True}} to pd.ExcelWriter, then write the DataFrame as usual.
My .xlsx would be 500 MB — why does it hit a 2 GB limit? The limit applies to each XML part before compression. Sheet XML compresses roughly four to one, so a 2 GiB sheet part becomes a workbook of around 500 MB.
Related
- Up one level: Troubleshooting Common Python Excel Errors — fixes for common failures.
- Write a Million Rows to Excel with xlsxwriter constant_memory — keeping big exports within memory.
- Working with Large Excel Files in Python — reading and writing at scale.
- Inspect the XML Inside an .xlsx File with Python — measuring the parts yourself.
More on errors & fixes
- FixHandle Permission Denied When Writing Excel in Python
- How-toWhat openpyxl Loses When You Save an Existing Workbook
- FixFix Excel Serial Numbers Showing Instead of Dates
- How-toHandle Daylight Saving Time in Excel Timestamps
- How-toHandle Microsoft Graph Throttling in Excel Automation
- GuideError Handling and Logging in Excel Automation