Validation & limits
Every document is checked before pandoc sees it, so bad files fail in milliseconds with a clear error.
What gets rejected
All of these exit with code 1 and leave any existing output untouched:
| Problem | Why it's rejected |
|---|---|
| Missing file, a directory, or the wrong extension | There's nothing to convert |
| Empty, truncated, or non-zip files | A .docx is a zip archive |
Password-protected and legacy .doc files | These aren't .docx files, even if they're named that way |
| Encrypted archive members | They can't be checked |
Member paths that are absolute or contain .. | A path traversal attempt |
| Duplicate member names | The checks and pandoc could read different copies |
| Missing required parts | It isn't a Word document |
| XML that isn't well-formed, in any part | pandoc can silently lose content from these. A bad relationships file makes it drop every link and still report success |
Any XML with a DOCTYPE | Word never writes one, and it enables entity attacks |
| A failed integrity check, or a size in the zip headers that's wrong | The file is corrupt or has been tampered with |
Limits
A very small .docx can expand enormously. In testing, a 3 KB document of nested tables exhausted a 4 GB memory limit in pandoc in 15 seconds. Now it's rejected almost instantly, before pandoc runs.
| Limit | Default | Change with | Applies |
|---|---|---|---|
| Input file size | 200 MiB | --max-file-size | Before pandoc |
| Total uncompressed size | 1 GiB | Python API | Before pandoc |
| Size of one XML part | 64 MiB | Python API | Before pandoc |
| Files in the archive | 10,000 | Python API | Before pandoc |
| XML nesting depth | 256 levels | Python API | Before pandoc |
| pandoc memory | 2 GiB | --max-memory | During conversion |
| pandoc run time | 120 seconds | --timeout | During conversion |
See the Limits class to change the ones without a command-line option.
How much memory you need
Memory depends mostly on how much text the document has, and whether it contains any media. These figures are peak memory measured with pandoc 3.13 on macOS, so treat them as a guide:
| Document | Peak memory |
|---|---|
| 10 MB of document XML, no media | About 320 MB |
| 1 MB of document XML, with an image | About 240 MB |
| 5 MB of document XML, with an image | About 1.1 GB |
| 10 MB of document XML, with an image | About 2.1 GB |
| A 50 MB image and little text | About 600 MB |
So a document with media takes about 200 MB of memory per MB of XML, because pandoc re-reads the whole page to embed the media. Large images themselves cost little. With the default 2 GiB limit, a document with media can have just under 10 MB of XML. Without media, the 64 MiB part limit normally applies first.
To see how much XML a document has, list its contents and look for word/document.xml:
unzip -l report.docx
Choosing limits
- Your own documents, and a long one fails
- Raise the limit that the error names:
--max-memory 8Gor--timeout 600. - Other people's documents
- Lower them to what your real documents need, such as
--max-memory 512M --timeout 30 --max-file-size 25M. The memory limit is a cap, not a target: a hostile file can use all of it before being stopped.
word2html reads the whole HTML into memory to check it, in addition to pandoc's use. --max-memory only limits pandoc, so allow some headroom on small machines.