PHPOffice/PHPWord · error · PhpOffice\PhpWord\Exception\Exception

The archive failed to load with the following error code…

Error message

The archive failed to load with the following error code: $openStatus

What it means

After the file-existence check, XMLReader::getDomFromZip() calls ZipArchive::open(). If it returns anything other than true (an integer ZipArchive error code such as ER_READ=5, ER_NOZIP=19, ER_INCONS=21), further ZipArchive calls would fatal, so the library throws with the numeric error code embedded in the message.

Solutions

  1. Decode the numeric code in the message (e.g. 19 = ZipArchive::ER_NOZIP, 21 = ER_INCONS) to identify the cause.
  2. Validate the archive before use: $z=new ZipArchive(); $z->open($path)===true, or check it's a real OOXML file (finfo mime zip + presence of [Content_Types].xml).
  3. Re-upload/re-download the file if truncated or corrupt; reject legacy .doc files and use the appropriate reader.
  4. Check file permissions and disk space if the file is a valid zip.

Example fix

// before
$zip = new ZipArchive();
$status = $zip->open($path); // returns 19, later fatal
// after
$zip = new ZipArchive();
$status = $zip->open($path);
if ($status !== true) {
    throw new RuntimeException("Corrupt or non-zip document ($status): $path");
}
Defensive patterns

Strategy: try-catch

Validate before calling

$zip = new ZipArchive();
if ($zip->open($path) !== true) {
    throw new InvalidArgumentException("Not a readable zip archive: $path");
}
$zip->close();

Try / catch

try {
    $reader->getDomFromZip($zipFile, $xmlFile);
} catch (\PhpOffice\PhpWord\Exception\Exception $e) {
    if (str_contains($e->getMessage(), 'failed to load with the following error code')) {
        $code = (int) filter_var($e->getMessage(), FILTER_SANITIZE_NUMBER_INT);
        throw new RuntimeException("Corrupt/non-zip document (ZipArchive code $code): $zipFile", $code, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: getDomFromZip() given a file that exists but is not a valid zip: old binary .doc saved as .docx, truncated download, password-protected zip, empty/corrupt archive, or a file without read permission (ZipArchive can stat but not open it).

Common situations: Users renaming legacy .doc to .docx; interrupted uploads; encrypted office files; disk full or permissions preventing ZipArchive from reading; corrupted templates in storage.

Related errors


AI-assisted analysis of PHPOffice/PHPWord@aef95c0415 (2026-09-14). Data as JSON: /api/errors/15c4f63e6ef81f39. Report an issue: GitHub.

Appendix: source

Thrown at src/PhpWord/Shared/XMLReader.php:71

     * @param string $zipFile
     * @param string $xmlFile
     *
     * @return DOMDocument|false
     */
    public function getDomFromZip($zipFile, $xmlFile)
    {
        if (file_exists($zipFile) === false) {
            throw new Exception('Cannot find archive file.');
        }

        $zip = new ZipArchive();
        $openStatus = $zip->open($zipFile);
        if ($openStatus !== true) {
            /**
             * Throw an exception since making further calls on the ZipArchive would cause a fatal error.
             * This prevents fatal errors on corrupt archives and attempts to open old "doc" files.
             */
            throw new Exception("The archive failed to load with the following error code: $openStatus");
        }

        $content = $zip->getFromName(ltrim($xmlFile, '/'));
        $zip->close();

        if ($content === false) {
            return false;
        }

        return $this->getDomFromString($content);
    }

    /**
     * Get DOMDocument from content string.
     *
     * @param string $content
     *
     * @return DOMDocument

View on GitHub (pinned to aef95c0415)