PHPOffice/PHPWord · critical · PhpOffice\PhpWord\Exception\Exception
Could not close zip file.
Error message
Could not close zip file.
What it means
TemplateProcessor::save() writes all modified parts back into the temporary zip archive and then closes it. If ZipArchive::close() returns false the archive could not be finalized — typically because the temp file is not writable, the disk is full, or the file is locked. The saved document is invalid or missing.
Solutions
- Check disk space and write permissions on the temp/output directory (sys_get_temp_dir() and the saveAs target).
- Ensure the output file is not open/locked by another process or held by antivirus/sync software.
- Call saveAs($path) to a fully writable path instead of relying on the default temp location.
- Retry the save once with a fresh TemplateProcessor instance if it persists.
Example fix
// before
$path = $processor->save(); // fails on read-only /tmp
// after
$processor->saveAs('/var/www/writable/output.docx'); Defensive patterns
Strategy: try-catch
Validate before calling
function canSaveTo(string $dir): bool {
return is_dir($dir) && is_writable($dir) && (disk_free_space($dir) === false || disk_free_space($dir) > 1024 * 1024);
} Try / catch
try {
$processor->saveAs($target);
} catch (\PhpOffice\PhpWord\Exception\Exception $e) {
if (str_contains($e->getMessage(), 'Could not close zip file')) {
error_log('Zip close failed: check disk space/locks on ' . $target);
$processor = null; // rebuild template processor and retry
} else { throw $e; }
} Prevention
- Monitor disk space on the temp directory and output volume.
- Never save to files that may be open in Word or held by sync/AV software.
- Save to local writable storage, then move to network/cloud storage after closing.
- Retry transient failures with a fresh TemplateProcessor instance.
When it happens
Trigger: Calling save()/saveAs() when the temporary document file cannot be written: read-only temp directory, insufficient disk space, file locked by another process (e.g. opened in Word), or the ZipArchive is in an inconsistent state.
Common situations: Servers with a full /tmp or read-only storage after deployment changes; concurrent processing of the same template file; antivirus or file-sync tools (OneDrive/Dropbox) locking the output file on Windows.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Cannot find archive file.
- The archive failed to load with the following error code…
- The file could not be deleted.
- Could not close zip file
- Directory does not exist: $directory
AI-assisted analysis of PHPOffice/PHPWord@aef95c0415 (2026-09-14).
Data as JSON: /api/errors/0ffa390868ce551f.
Report an issue: GitHub.
Appendix: source
Thrown at src/PhpWord/TemplateProcessor.php:1014
*/
public function save()
{
foreach ($this->tempDocumentHeaders as $index => $xml) {
$this->savePartWithRels($this->getHeaderName($index), $xml);
}
$this->savePartWithRels($this->getMainPartName(), $this->tempDocumentMainPart);
$this->savePartWithRels($this->getSettingsPartName(), $this->tempDocumentSettingsPart);
foreach ($this->tempDocumentFooters as $index => $xml) {
$this->savePartWithRels($this->getFooterName($index), $xml);
}
$this->zipClass->addFromString($this->getDocumentContentTypesName(), $this->tempDocumentContentTypes);
// Close zip file
if (false === $this->zipClass->close()) {
throw new Exception('Could not close zip file.'); // @codeCoverageIgnore
}
return $this->tempDocumentFilename;
}
/**
* @param string $fileName
* @param string $xml
*/
protected function savePartWithRels($fileName, $xml): void
{
$this->zipClass->addFromString($fileName, $xml);
if (isset($this->tempDocumentRelations[$fileName])) {
$relsFileName = $this->getRelationsName($fileName);
$this->zipClass->addFromString($relsFileName, $this->tempDocumentRelations[$fileName]);
}
}
View on GitHub (pinned to aef95c0415)