Heuristic:Protectai Modelscan Nested Zip Not Supported
| Knowledge Sources | |
|---|---|
| Domains | Security, Debugging |
| Last Updated | 2026-02-14 12:00 GMT |
Overview
ModelScan does not support nested zip files (zip within zip). Nested zips are reported as errors and their contents are not scanned.
Description
When ModelScan iterates through model files, it extracts entries from top-level zip and npz archives for scanning. However, if an extracted entry is itself a zip file (nested zip), ModelScan raises a `NestedZipError` and skips that entry entirely. This is a deliberate design limitation — parsing nested archives would require recursive extraction with protection against zip bombs and infinite nesting, which is out of scope for the current implementation.
Usage
Be aware of this limitation when scanning model archives that contain other archives. If you encounter `NestedZipError` messages, extract the inner archives manually and scan them separately. This is particularly relevant for PyTorch models saved with custom bundling or datasets distributed as nested archives.
The Insight (Rule of Thumb)
- Action: If scanning nested zip files, extract inner archives to disk first and scan them separately.
- Value: ModelScan supports `.zip` and `.npz` as top-level archive formats only.
- Trade-off: Reduced scanning depth in exchange for simpler, safer archive handling. Avoids zip bomb risks.
Reasoning
From `modelscan/modelscan.py:103-110`, when a zip entry is itself detected as a zip file via the `_is_zipfile()` check, ModelScan appends a `NestedZipError` and calls `continue` to skip that entry:
with zip.open(file_name, "r") as file_io:
file_name = f"{model.get_source()}:{file_name}"
if _is_zipfile(file_name, data=file_io):
self._errors.append(
NestedZipError(
"ModelScan does not support nested zip files.",
Path(file_name),
)
)
continue
The `BadZipFile` and `RuntimeError` exceptions from corrupted zip data are also caught gracefully at `modelscan.py:113-126`, preventing crashes on malformed archives:
except (zipfile.BadZipFile, RuntimeError) as e:
logger.debug(
"Skipping zip file %s, due to error",
str(model.get_source()),
exc_info=True,
)
The supported top-level zip extensions are defined in `settings.py:30`:
"supported_zip_extensions": [".zip", ".npz"],