conductor-oss/conductor · error · IllegalArgumentException
Skill package exceeds max uncompressed size of {maxUncompres
Error message
Skill package exceeds max uncompressed size of {maxUncompressedBytes} bytes What it means
Thrown by parseSkillPackage when the cumulative uncompressed size across all entries exceeds maxUncompressedBytes (default 209,715,200 = 200 MiB, configurable via agentspan.skills.max-uncompressed-bytes). This is the zip-bomb defense: it sums bytes during streaming decompression and aborts when the total crosses the cap, regardless of how small the compressed input is.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java:460
throw new IllegalArgumentException(
"Skill package contains duplicate path: " + path);
}
MessageDigest digest = MessageDigest.getInstance("SHA-256");
long size = 0;
ByteArrayOutputStream content = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int read;
while ((read = zip.read(buffer)) >= 0) {
digest.update(buffer, 0, read);
content.write(buffer, 0, read);
size += read;
totalUncompressedBytes += read;
if (size > maxPackageBytes) {
throw new IllegalArgumentException(
"Skill package contains oversized file: " + path);
}
if (totalUncompressedBytes > maxUncompressedBytes) {
throw new IllegalArgumentException(
"Skill package exceeds max uncompressed size of "
+ maxUncompressedBytes
+ " bytes");
}
}
contentByPath.put(path, content.toByteArray());
files.add(
SkillFileEntry.builder()
.path(path)
.size(size)
.sha256(hex(digest.digest()))
.contentType(contentType(path))
.build());
}
} catch (IllegalArgumentException e) {
throw e;
} catch (Exception e) {
throw new IllegalArgumentException("Invalid skill package zip: " + e.getMessage(), e);View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Reduce the total uncompressed content of the package below the limit.
- Raise agentspan.skills.max-uncompressed-bytes if the large total is intentional and trusted.
- Scan uploaded packages for zip bombs before they reach this service if untrusted uploads are accepted.
Example fix
# application.yml
agentspan:
skills:
max-uncompressed-bytes: 524288000 # 500 MiB Defensive patterns
Strategy: validation
Validate before calling
// Before zipping, sum uncompressed sizes of all included files
long total = includedFiles.stream().mapToLong(p -> { try { return Files.size(p); } catch (IOException e) { return 0; } }).sum();
if (total > maxUncompressedBytes) throw new IllegalArgumentException("uncompressed total too large: " + total); Type guard
static boolean withinUncompressedTotal(long total, long maxUncompressedBytes) { return total <= maxUncompressedBytes; } Try / catch
try { skillRegistryService.register(manifest, pkg); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("max uncompressed size")) { /* reduce content or raise limit */ }
else throw e;
} Prevention
- Treat any untrusted upload as a potential zip bomb and pre-scan total uncompressed size.
- Keep skill packages lean; host bulky assets externally.
When it happens
Trigger: POST /api/skills/register with a zip bomb — a tiny compressed file that decompresses to hundreds of MiB — or a legitimately large package whose combined uncompressed content exceeds 200 MiB. Checked incrementally so it trips mid-decompression.
Common situations: An adversarial or accidentally nested zip; bundling many large assets; lowering max-uncompressed-bytes in a shared config; vendoring a large dependency tree uncompressed.
Related errors
- Skill package exceeds max file count of {maxFileCount}
- Skill package contains oversized file: {path}
- Skill file is too large to preview: {cleanPath}
- Failed to read skill file: {e.getMessage()}
- Skill package exceeds max size of {maxPackageBytes} bytes
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/86c2ffe8f8ec9000.
Report an issue: GitHub.