getgrav/grav · error · RuntimeException
ZipArchiver: ZIP failed to extract {archive_file} to {destin
Error message
ZipArchiver: ZIP failed to extract {archive_file} to {destination} What it means
When the uncompressed-size cap is disabled (maxSize = 0), ZipArchiver::extract() falls back to the native ZipArchive::extractTo($destination); if that call returns false, the archive is closed and RuntimeException 'ZipArchiver: ZIP failed to extract <file> to <destination>' is thrown. This is a raw extraction failure — permission, space, or archive-integrity level — with no further detail because PHP's ZipArchive does not expose one here.
Source
Thrown at system/src/Grav/Common/Filesystem/ZipArchiver.php:104
$totalSize += (int) $stat['size'];
if ($totalSize > $maxSize) {
$zip->close();
throw new RuntimeException('ZipArchiver: refused to extract ' . $this->archive_file . '. Archive exceeds the maximum uncompressed size (' . $maxSize . ' bytes).');
}
}
}
}
Folder::create($destination);
if ($maxSize > 0) {
// Enforce the uncompressed-size cap against bytes actually written,
// so a forged-small declared size cannot smuggle a bomb past the
// advisory pre-pass above (GHSA-8h9x-89f2-m7x3).
$this->extractStreamed($zip, $destination, $numFiles, $maxSize);
} elseif (!$zip->extractTo($destination)) {
$zip->close();
throw new RuntimeException('ZipArchiver: ZIP failed to extract ' . $this->archive_file . ' to ' . $destination);
}
$zip->close();
return $this;
}
throw new RuntimeException('ZipArchiver: Failed to open ' . $this->archive_file);
}
/**
* Resolve the uncompressed-size / file-count / nesting-depth caps applied
* before extraction. Shares the same config keys and defaults as
* GPM\Installer so both ZIP extraction paths enforce identical limits. A
* limit of 0 disables that particular check.
*
* @return array{0:int,1:int,2:int} [maxUncompressedBytes, maxFiles, maxDepth]
*/View on GitHub (pinned to 6040efed04)
Solutions
- Verify writability of the destination and free space: is_writable($dest), df -h
- Test the archive independently: unzip -t package.zip to detect corruption; re-download if it fails
- Re-run the extraction once the environment issue (space/permissions/lock) is fixed
- If you need size-cap enforcement too, keep max_uncompressed_size > 0 so the streamed path with better errors is used
Defensive patterns
Strategy: try-catch
Validate before calling
if (!is_dir($destination) || !is_writable($destination)) {
throw new RuntimeException("Destination {$destination} missing or not writable");
}
if (disk_free_space($destination) < $expectedSize) {
throw new RuntimeException('Insufficient disk space for extraction');
} Try / catch
try {
(new ZipArchiver($path))->extract($destination);
} catch (RuntimeException $e) {
if (str_contains($e->getMessage(), 'failed to extract')) {
// ZipArchive::extractTo returned false: check perms/space, verify with unzip -t, then retry once
}
} Prevention
- Pre-create and chmod destination directories before extraction
- Monitor disk space on install endpoints — extractTo fails silently on ENOSPC
- Keep max_uncompressed_size > 0 so the streamed extractor (with abort/rollback) is used instead of raw extractTo
When it happens
Trigger: Destination directory not writable by the PHP process; disk full during extraction; archive corrupted mid-file so extractTo aborts; extracting into a path blocked by open_basedir; concurrent extraction into the same destination clobbering entries.
Common situations: Plugin/theme install into user/ when the web user lacks write permission; low-disk VPS deployments; truncated downloads of package zips; two simultaneous installs targeting the same folder.
Related errors
- ZipArchiver: refused to extract {archive_file}. Archive exce
- ZipArchiver: refused to extract {archive_file}. Entry "{name
- ZipArchiver: refused to extract {archive_file}. Entry "{name
- ZipArchiver: refused to extract {archive_file}. Archive exce
- ZipArchiver: Failed to open {archive_file}
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/91f8be4dcd4e7254.
Report an issue: GitHub.