alibaba/nacos · error · NacosApiException
PARSING_DATA_FAILED
PARSING_DATA_FAILED
Error message
Failed to parse zip file: " + e.getMessage()
What it means
Thrown by SkillZipParser.parseSkillFromZip as the catch-all for any non-NacosApiException exception during ZIP parsing. This covers failures in unzipToEntries (ZipArchiveInputStream errors, security-limit violations via NacosRuntimeException), parseSkillMarkdown (invalid YAML, missing frontmatter), and parseResources. The original exception is logged and its message is included in the error.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/utils/SkillZipParser.java:248
if (StringUtils.isBlank(skillMdContent)) {
throw new NacosApiException(NacosApiException.INVALID_PARAM,
ErrorCode.PARAMETER_VALIDATE_ERROR,
"SKILL.md file not found in zip");
}
Skill skill = parseSkillMarkdown(skillMdContent, namespaceId);
List<ZipEntryData> resourceEntries =
filterEntriesByPrefix(entries, getSkillPrefix(skillMdEntry.name));
Map<String, SkillResource> resources =
parseResources(resourceEntries, skill.getName(), SKILL_MD_FILE);
skill.setResource(resources);
return skill;
} catch (NacosApiException e) {
throw e;
} catch (Exception e) {
LOGGER.error("Failed to parse skill zip file", e);
throw new NacosApiException(NacosApiException.INVALID_PARAM,
ErrorCode.PARSING_DATA_FAILED,
"Failed to parse zip file: " + e.getMessage());
}
}
/**
* Parse multiple skills from a single zip archive. Supports zip files containing multiple skill subdirectories,
* each with its own SKILL.md. If only one SKILL.md is found, returns a list with a single element.
*
* <p>Expected zip structure for multi-skill:
* <pre>
* skills.zip
* ├── skill-a/
* │ ├── SKILL.md
* │ └── resource.txt
* ├── skill-b/
* │ ├── SKILL.md
* │ └── template/prompt.mdView on GitHub (pinned to 9b989acdf1)
Solutions
- Check server logs for the full stack trace — the chained exception (e) identifies the exact cause.
- If the ZIP is corrupted, re-download or re-create it from the source.
- If the error is a security-limit violation (too many entries, uncompressed size exceeded), raise nacos.ai.skill.zip.max-entries or nacos.ai.skill.zip.max-uncompressed-size-mb if the skill legitimately needs more.
- If the error is a path-traversal rejection, inspect the ZIP for entries containing '..' or absolute paths and remove them.
- If the error is YAML-related, validate the SKILL.md frontmatter syntax with a YAML linter before zipping.
Example fix
// before — ZIP contains a path-traversal entry // entry: ../../../etc/passwd // after — re-create ZIP without malicious entries // zip -r skill.zip SKILL.md resources/ (from inside the skill directory) // verify: unzip -l skill.zip (no entries with '..')
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate ZIP structure before calling parseSkillFromZip
if (zipBytes == null || zipBytes.length == 0) {
throw new IllegalArgumentException("ZIP is empty");
}
// Check ZIP magic bytes
if (zipBytes.length < 4 || (zipBytes[0] != 0x50 || zipBytes[1] != 0x4B)) {
throw new IllegalArgumentException("Not a valid ZIP file (missing PK magic bytes)");
} Type guard
public static boolean isValidZipArchive(byte[] zipBytes) {
return zipBytes != null && zipBytes.length >= 4
&& zipBytes[0] == 0x50 && zipBytes[1] == 0x4B // PK magic
&& zipBytes.length <= SkillZipParser.resolveMaxUploadBytes();
} Try / catch
try {
Skill skill = SkillZipParser.parseSkillFromZip(zipBytes, namespaceId);
} catch (NacosApiException e) {
if (ErrorCode.PARSING_DATA_FAILED.equals(e.getErrDetail())) {
log.error("Failed to parse skill ZIP: {}", e.getErrMsg(), e);
return ResponseEntity.badRequest()
.body("Could not parse the ZIP file. Check the archive integrity and SKILL.md format. Detail: "
+ e.getErrMsg());
}
throw e;
} Prevention
- Validate the ZIP magic bytes (PK) before parsing to catch non-ZIP files early.
- Run unzip -t skill.zip to test archive integrity before uploading.
- Validate SKILL.md YAML frontmatter syntax with a YAML linter.
- Inspect ZIP entries for path traversal ('..') before uploading.
- Raise max-entries / max-uncompressed-size-mb if legitimate large skills are rejected.
When it happens
Trigger: Uploading a ZIP that triggers any unexpected exception during parsing: a corrupted ZIP archive that Apache Commons Compress cannot read; a path-traversal entry ('../') caught by SkillUtils.validatePathSafety; a ZIP bomb exceeding the uncompressed size limit; a SKILL.md with malformed YAML frontmatter; a resource entry with an invalid name pattern.
Common situations: Corrupted or truncated ZIP file from a failed download; a ZIP created by a tool that produces entries Apache Commons Compress cannot handle; a malicious or accidental path-traversal entry in the ZIP; exceeding the max-entries or max-uncompressed-size limits; SKILL.md YAML frontmatter that is syntactically broken (e.g. missing colon, unbalanced quotes).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/f5a928dc517cc29e.
Report an issue: GitHub.