How to Fix ZIP Extraction Errors: 7 Common Causes
ZIP extraction errors often look alike even when their causes differ. Start by identifying whether the archive is damaged, mislabeled, encrypted, unsupported, blocked by the destination, or unsafe to extract.
Diagnose the error first
| Error or symptom | Likely cause | First command |
|---|---|---|
End-of-central-directory signature not found | Truncated or corrupted ZIP | unzip -t archive.zip |
Unknown format or an extractor opens HTML/text | The download is not actually a ZIP | file archive.zip |
Bad password or Wrong password | Encrypted ZIP or incorrect password | 7z t -pYOUR_PASSWORD archive.zip |
Unsupported compression method | The extractor does not support the method used | 7z l -slt archive.zip |
| Garbled, invalid, or overly long filename | Encoding or path-length problem | 7z l archive.zip |
| Cannot create a file, or extraction stops mid-run | Conflict, permission, or insufficient disk space | df -h . |
| A security scanner blocks parent-directory paths | Path traversal (Zip Slip) | zipinfo -1 archive.zip |
1. The ZIP is truncated or corrupted
The central directory is normally near the end of a ZIP. An interrupted download can remove it even when the file still begins with a valid PK signature.
unzip -t archive.zip
file archive.zip
xxd -l 4 archive.zip
A normal local-file header begins with 50 4b 03 04, but that signature alone does not prove the whole archive is valid. Re-download from the source and compare its published checksum when one is available.
Use the intentionally corrupt ZIP to confirm that your application reports a controlled error instead of crashing.
2. The file is not actually a ZIP
Servers sometimes return an HTML login page, quota error, or JSON response that gets saved with a .zip extension. Check the detected type before trying repair tools.
file archive.zip
head -c 80 archive.zip
If the output identifies HTML or text, fix the download URL, authentication, or redirect handling and download the file again.
3. The ZIP is password-protected
Test an encrypted archive without extracting it:
7z t -pYOUR_PASSWORD archive.zip
Do not place real production passwords in shell history or source code. For a safe fixture, use the password-protected ZIP with the documented test password test123.
4. The compression method is unsupported
ZIP is a container and can use different compression methods. Inspect the archive before choosing a library:
7z l -slt archive.zip
Python's zipfile supports stored, Deflate, BZIP2, and LZMA ZIP entries. Zstandard ZIP support depends on the Python version and runtime, so check the documentation for the environment you deploy. If a consumer cannot decode the method, update it or recreate the archive using a supported method such as Deflate.
5. Filenames or paths are incompatible
Older archives may not mark filenames as UTF-8, while Windows paths can also exceed limits accepted by older applications. List entries before extraction:
7z l archive.zip
Extract into a short, empty destination path and use a current extractor that honors the ZIP UTF-8 flag. Avoid silently rewriting names unless your application records the mapping.
6. The destination cannot accept the files
Existing files, permissions, quotas, or a large uncompressed size can stop extraction even when the ZIP is valid.
df -h .
du -sh output 2>/dev/null
7z l archive.zip
Use a fresh destination directory, verify write permission, and compare available space with the total uncompressed size shown by the listing command.
7. The archive contains unsafe paths
A ZIP entry such as ../../../etc/passwd can escape the intended output directory. Treat this as a security failure, not an extraction inconvenience. Resolve every destination path and reject entries outside the target directory before writing.
const fs = require("fs");
const path = require("path");
const AdmZip = require("adm-zip");
const zip = new AdmZip("upload.zip");
const targetDir = path.resolve("/tmp/extracted");
for (const entry of zip.getEntries()) {
const destination = path.resolve(targetDir, entry.entryName);
const insideTarget = destination === targetDir || destination.startsWith(targetDir + path.sep);
if (!insideTarget) throw new Error(`Unsafe ZIP path: ${entry.entryName}`);
if (entry.isDirectory) {
fs.mkdirSync(destination, { recursive: true });
} else {
fs.mkdirSync(path.dirname(destination), { recursive: true });
fs.writeFileSync(destination, entry.getData());
}
}
Production code should also reject absolute paths, links, excessive expansion ratios, too many entries, and output that exceeds configured limits.
Test matrix
| Test case | Direct sample | Expected result |
|---|---|---|
| Valid archive | 100MB valid ZIP | Opens and extracts successfully |
| Password handling | Password-protected ZIP | Requires password test123 |
| Corruption handling | Intentionally corrupt ZIP | Fails with a controlled error |
| Large-file handling | Exact 1GB ZIP | Exercises storage, streaming, and timeout limits |
See also: Archive Formats Cheat Sheet · TAR.GZ files · 7Z files