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
- Verify the archive exists with file_exists()/is_file() before loading and print the resolved absolute path (realpath()) in logs.
- Use absolute paths for the zip file; fix relative-path/working-directory issues.
- Download remote templates to a local temp file before passing them.
- 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
- Store templates with absolute paths; log realpath() on failure
- Never pass URLs or stream wrappers where a local file path is required
- Confirm upload persistence (move_uploaded_file) before processing
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
- Invalid image
- Could not load image $originSrc
- Could not open ' . $sFileName . ' for reading! File does…
- The archive failed to load with the following error code…
- Could not close zip file.
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)