Leantime/leantime · error · Exception
notification.plugin_zip_malloc
Error message
notification.plugin_zip_malloc
What it means
The match maps ZipArchive::ER_MEMORY to 'Zip: Malloc failure'. libzip could not allocate the memory it needs to index the archive while opening it. This is not about the zip being bad - it is the PHP process hitting its memory ceiling (memory_limit) or a container cgroup memory cap during open().
Source
Thrown at app/Domain/Plugins/Services/Plugins.php:738
if (
is_dir($pluginDir = "{$this->pluginDirectory}{$foldername}")
&& ! File::deleteDirectory($pluginDir)
) {
throw new \Exception(__('notification.plugin_cant_remove'));
}
if (! mkdir($pluginDir) && ! is_dir($pluginDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $pluginDir));
}
$zip = new \ZipArchive;
match ($zip->open($temporaryFile)) {
\ZipArchive::ER_EXISTS => throw new \Exception(__('notification.plugin_zip_exists')),
\ZipArchive::ER_INCONS => throw new \Exception(__('notification.plugin_zip_inconsistent')),
\ZipArchive::ER_INVAL => throw new \Exception(__('notification.plugin_zip_invalid_arg')),
\ZipArchive::ER_MEMORY => throw new \Exception(__('notification.plugin_zip_malloc')),
\ZipArchive::ER_NOENT => throw new \Exception(__('notification.plugin_zip_no_file')),
\ZipArchive::ER_NOZIP => throw new \Exception(__('notification.plugin_zip_not_zip')),
\ZipArchive::ER_OPEN => throw new \Exception(__('notification.plugin_zip_cant_open')),
\ZipArchive::ER_READ => throw new \Exception(__('notification.plugin_zip_read_err')),
\ZipArchive::ER_SEEK => throw new \Exception(__('notification.plugin_zip_seek_err')),
default => throw new \Exception(__('notification.plugin_zip_unknown_err')),
true => null,
};
if (! $zip->extractTo($pluginDir)) {
throw new \Exception(__('notification.plugin_zip_cant_extract'));
}
$zip->close();
unlink($temporaryFile);
// read the composer.json content from the plugin phar fileView on GitHub (pinned to 9a9f49f100)
Solutions
- Check the web SAPI's actual limit: php -r via a phpinfo page or ini_get('memory_limit') rendered from a route - raise it (e.g. 512M) for the install.
- Raise the container/pod memory limit if the process is being OOM-capped.
- Retry the install when the server is less loaded (other requests consume the same limit).
- If a custom build has no zlib support, verify the zip extension is fully functional: php -m | grep zip.
Defensive patterns
Strategy: validation
Validate before calling
$limit = ini_get('memory_limit');
if ($limit !== '-1' && parseByteSize($limit) < 256 * 1024 * 1024) {
ini_set('memory_limit', '512M'); // raise for the duration of the plugin install
} Prevention
- Set memory_limit of at least 256-512M for requests that install plugins.
- Check the web SAPI's limit (not CLI's) - they differ.
- Size container memory limits with plugin installs in mind.
When it happens
Trigger: installMarketplacePlugin() opening a large plugin zip under a low memory_limit (shared hosting defaults of 64-128M are common victims), or a container whose memory cgroup limit is near exhaustion; memory pressure from other concurrent requests finishing the budget.
Common situations: Shared hosting with low memory_limit installing asset-heavy plugins; Kubernetes pod memory limits; php.ini memory_limit left at a small value for the web SAPI while CLI has a higher one.
Related errors
- notification.plugin_zip_exists
- notification.plugin_zip_inconsistent
- notification.plugin_zip_not_zip
- notification.plugin_zip_unknown_err
- notification.plugin_cant_download
AI-assisted analysis of Leantime/leantime@9a9f49f100 (2026-08-21).
Data as JSON: /api/errors/a0b5fc522264c4d5.
Report an issue: GitHub.