chatboxai/chatbox · error
ZIP entry compression ratio is unsafe: ${entry.name}
Error message
ZIP entry compression ratio is unsafe: ${entry.name} What it means
Per-entry zip-bomb guard: thrown when the entry's declared uncompressed size exceeds 1 MiB AND exceeds Math.max(1, entry.size) * entryLimits.maxCompressionRatio (default 2000x). It catches a small compressed payload that would balloon on inflation, using the header sizes so it fires before the data callback streams much content.
Source
Thrown at src/renderer/packages/backup/zip.ts:238
const unzip = new Unzip((entry) => {
try {
throwIfAborted(options.signal)
assertSafeArchivePath(entry.name)
if (seenPaths.has(entry.name)) throw new Error(`Duplicate ZIP entry: ${entry.name}`)
seenPaths.add(entry.name)
entryCount++
if (entryCount > limits.maxEntries) throw new Error('ZIP contains too many entries')
const entryLimits = { ...limits, ...options.entryLimits?.(entry.name) }
if (entry.originalSize !== undefined && entry.originalSize > entryLimits.maxEntryUncompressedBytes) {
throw new Error(`ZIP entry is too large: ${entry.name}`)
}
if (
entry.size !== undefined &&
entry.originalSize !== undefined &&
entry.originalSize > 1024 * 1024 &&
entry.originalSize > Math.max(1, entry.size) * entryLimits.maxCompressionRatio
) {
throw new Error(`ZIP entry compression ratio is unsafe: ${entry.name}`)
}
const chunks: Uint8Array[] = []
let entryBytes = 0
entry.ondata = (error, data, final) => {
if (fatalError) return
if (error) {
fatalError = error
return
}
entryBytes += data.length
totalUncompressedBytes += data.length
if (entryBytes > entryLimits.maxEntryUncompressedBytes) {
fatalError = new Error(`ZIP entry is too large: ${entry.name}`)
entry.terminate()
return
}
if (totalUncompressedBytes > limits.maxTotalUncompressedBytes) {View on GitHub (pinned to 81571269ad)
Solutions
- If high-ratio entries are legitimate for trusted paths, raise maxCompressionRatio via limits or entryLimits for those paths.
- Reject the archive for untrusted imports; a >2000x ratio is almost always pathological.
- Re-export without pathological padding/repetition on the producer side.
Example fix
// before
await readZipFileEntries(file, onEntry)
// after: raise the ratio cap for a trusted, highly-compressible log path
await readZipFileEntries(file, onEntry, {
entryLimits: (path) =>
path.endsWith('.log') ? { maxCompressionRatio: 10_000 } : {}
}) Defensive patterns
Strategy: validation
Validate before calling
// Raise maxCompressionRatio for trusted, highly-compressible paths only.
await readZipFileEntries(file, onEntry, {
entryLimits: (path) =>
path.endsWith('.log') ? { maxCompressionRatio: 10_000 } : {},
}) Try / catch
try {
await readZipFileEntries(file, onEntry, opts)
} catch (error) {
if (error instanceof Error && error.message.startsWith('ZIP entry compression ratio is unsafe')) {
// For untrusted sources this is a zip-bomb: reject. For trusted logs, raise the cap.
} else throw error
} Prevention
- Keep the default 2000x cap for untrusted archives; a higher ratio is almost always a zip-bomb.
- Narrow ratio overrides to specific trusted paths (e.g. *.log).
- Re-export without pathological padding/repetition on the producer side.
When it happens
Trigger: A highly compressible entry (e.g. repeated bytes) whose compressed size is tiny relative to its uncompressed size, or a deliberately crafted zip-bomb entry.
Common situations: Test/security zip-bombs, log files full of repetition, or an exporter that compressed a sparse/padding-heavy blob.
Related errors
- ZIP archive compression ratio is unsafe
- ZIP contains too many entries
- ZIP entry is too large: ${entry.name}
- ZIP archive central directory is invalid
- Duplicate ZIP entry: ${entry.name}
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/c3404f3f3222cd81.
Report an issue: GitHub.