PHPOffice/PHPWord · error · Exception

Cannot find archive file.

Error message

Cannot find archive file.

What it means

XMLReader::getDomFromZip() opens a OOXML package (.docx/.xlsx-style zip) to extract an XML part. Its first check is file_exists($zipFile); if the archive file does not exist on disk, Exception('Cannot find archive file.') is thrown before any zip handling.

Solutions

  1. Verify the archive exists with file_exists()/is_file() before loading and print the resolved absolute path (realpath()) in logs.
  2. Use absolute paths for the zip file; fix relative-path/working-directory issues.
  3. Download remote templates to a local temp file before passing them.
  4. Check upload handling so the file is stored (move_uploaded_file) before processing.

Example fix

// before
$template = 'https://example.com/tpl.docx';
$reader->getDomFromZip($template, 'word/document.xml');
// after
$local = sys_get_temp_dir() . '/tpl.docx';
copy('https://example.com/tpl.docx', $local);
if (!file_exists($local)) {
    throw new RuntimeException("Template missing: $local");
}
$reader->getDomFromZip($local, 'word/document.xml');
Defensive patterns

Strategy: validation

Validate before calling

if (!is_string($zipFile) || !is_file($zipFile)) {
    throw new InvalidArgumentException("Archive does not exist: " . var_export($zipFile, true));
}

Type guard

function isExistingFile(mixed $path): bool
{
    return is_string($path) && is_file($path);
}

Try / catch

try {
    $reader->getDomFromZip($zipFile, $xmlFile);
} catch (\PhpOffice\PhpWord\Exception\Exception $e) {
    if ($e->getMessage() === 'Cannot find archive file.') {
        throw new RuntimeException("Document package missing at $zipFile", 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling getDomFromZip() (directly or via reader flows like read(), readRelationships(), getRels(), readHeaderFooter()) with a path that does not exist — wrong path, file not yet written, or reading a stream/remote URL that this method does not support.

Common situations: Passing a URL or php:// stream to a template loader; template file deleted between upload and processing; working directory mismatch for relative paths; forgetting to save a generated temp file first.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

    /**
     * DOMXpath object.
     *
     * @var DOMXpath
     */
    private $xpath;

    /**
     * Get DOMDocument from ZipArchive.
     *
     * @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;
        }

View on GitHub (pinned to aef95c0415)