alibaba/nacos · error · NacosException
SERVER_ERROR
SERVER_ERROR
Error message
Downloaded ZIP contains unsafe entry paths: %s
What it means
Thrown by AiHttpClientProxy.downloadSkillZip after SkillUtils.validateZipEntryPaths detects an unsafe (zip-slip or otherwise malicious) entry path in the downloaded skill ZIP. validateZipBytes already confirmed non-empty content; this second guard blocks path-traversal entries that could escape the extraction target. SERVER_ERROR reflects a corrupt or malicious server payload.
Source
Thrown at client/src/main/java/com/alibaba/nacos/client/ai/remote/AiHttpClientProxy.java:314
params.put("namespaceId", namespaceId);
params.put("name", skillName);
if (StringUtils.isNotBlank(version)) {
params.put("version", version);
}
if (StringUtils.isNotBlank(label)) {
params.put("label", label);
}
RequestResource resource = RequestResource.aiBuilder().setNamespace(namespaceId)
.setGroup(com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP)
.setResource(null == skillName ? StringUtils.EMPTY : skillName).build();
byte[] zipBytes = reqApiBytes(SKILL_DOWNLOAD_PATH, params, resource);
SkillUtils.validateZipBytes(zipBytes);
try {
SkillUtils.validateZipEntryPaths(zipBytes);
} catch (Exception e) {
throw new NacosException(NacosException.SERVER_ERROR,
"Downloaded ZIP contains unsafe entry paths: " + e.getMessage(), e);
}
return zipBytes;
}
@Override
public SkillQueryResponse querySkill(String skillName, String version, String label, String md5)
throws NacosException {
Map<String, String> params = new HashMap<>(8);
params.put("namespaceId", namespaceId);
params.put("name", skillName);
if (StringUtils.isNotBlank(version)) {
params.put("version", version);
}
if (StringUtils.isNotBlank(label)) {
params.put("label", label);
}
if (StringUtils.isNotBlank(md5)) {View on GitHub (pinned to 9b989acdf1)
Solutions
- Inspect the downloaded ZIP entries to confirm which path triggered the guard (the exception message lists them).
- Re-publish the skill from a clean, correctly-packaged build that uses relative, in-bounds entry paths.
- If untrusted, do not extract; quarantine the package and audit the skill source.
- Ensure the skill build tooling normalizes entry paths before zipping.
Example fix
// before: skill built with absolute/traversal entry names // after: build with normalized relative paths, e.g. // zip entries like "skills/my-skill/manifest.json" (no leading / or ../)
Defensive patterns
Strategy: validation
Validate before calling
// Before publishing a skill, validate its entries locally:
SkillUtils.validateZipEntryPaths(Files.readAllBytes(Path.of("skill.zip"))); Try / catch
try {
client.downloadSkillZip(name, version, label);
} catch (NacosException e) {
if (e.getErrCode() == NacosException.SERVER_ERROR
&& e.getMessage().contains("unsafe entry paths")) {
// do not extract; quarantine and republish with normalized entry paths
}
throw e;
} Prevention
- Build skill ZIPs with normalized, relative, in-bounds entry paths.
- Validate ZIP entries before publishing to the server.
- Never extract untrusted skill packages; audit their contents.
When it happens
Trigger: The server returns a skill ZIP containing an entry whose path traverses outside the intended directory (e.g. ../../etc/passwd) or otherwise violates the safe-path contract; SkillUtils.validateZipEntryPaths raises and the client wraps it.
Common situations: A tampered or maliciously crafted skill package on the server; a packaging bug in the skill build that emitted absolute or traversal paths; server-side zip assembly regression producing invalid entry names.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/ca2ef73b8491abec.
Report an issue: GitHub.