theonedev/onedev · error · ClientException
Chart.yaml not found in the archive
Error message
Chart.yaml not found in the archive
What it means
Thrown when the chart archive was read successfully but no entry named Chart.yaml (at archive root) was found, leaving metadata null. OneDev requires Chart.yaml to extract the chart name and version, so a chart without it is rejected with 400 Bad Request.
Source
Thrown at server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java:208
TarEntry entry;
while ((entry = is.getNextEntry()) != null) {
String entryName = entry.getName();
if (entryName.equals("Chart.yaml") || entryName.endsWith("/Chart.yaml")) {
if (entry.getSize() > MAX_FILE_SIZE)
throw new ClientException(SC_BAD_REQUEST, "Chart.yaml is too large");
byte[] content = new byte[(int) entry.getSize()];
is.read(content);
var options = new LoaderOptions();
metadata = new Yaml(new SafeConstructor(options)).load(new ByteArrayInputStream(content));
break;
}
}
} catch (IOException e) {
throw new ClientException(SC_BAD_REQUEST, "Error reading chart archive: " + e.getMessage());
}
if (metadata == null) {
throw new ClientException(SC_BAD_REQUEST, "Chart.yaml not found in the archive");
}
var chartName = (String) metadata.get("name");
var chartVersion = (String) metadata.get("version");
if (chartName == null || chartVersion == null) {
throw new ClientException(SC_BAD_REQUEST, "Chart name or version not specified");
}
var finalMetadata = metadata;
var lockName = "update-pack:" + projectId + ":" + HelmPackSupport.TYPE + ":" + chartName + ":" + chartVersion;
LockUtils.run(lockName, () -> transactionService.run(() -> {
var project = projectService.load(projectId);
PackBlob packBlob = packBlobService.load(packBlobService.uploadBlob(projectId, bytes, null));
var data = new HelmData(finalMetadata, packBlob.getSha256Hash());
Pack pack = packService.findByNameAndVersion(project, HelmPackSupport.TYPE, chartName, chartVersion);
if (pack == null) {View on GitHub (pinned to d44925c47c)
Solutions
- Run 'helm package <chart-dir>' so Chart.yaml is included at the archive root
- Confirm 'tar tzf chart.tgz' lists Chart.yaml at the root of the archive
- If Chart.yaml is nested under a folder, restructure/repackage so it is at the top level
- Ensure you are uploading the chart tgz, not a .prov file or other artifact
Example fix
// before (manual archive missing Chart.yaml) tar czf mychart.tgz templates/ values.yaml // after helm package mychart # includes Chart.yaml at root
Defensive patterns
Strategy: validation
Validate before calling
boolean hasChartYaml = false;
try (var tar = new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream(tgz)))) {
TarArchiveEntry e;
while ((e = tar.getNextTarEntry()) != null)
if (!e.isDirectory() && e.getName().replaceFirst("^[^/]+/", "").equals("Chart.yaml")) { hasChartYaml = true; break; }
}
if (!hasChartYaml) throw new IllegalArgumentException("archive must contain Chart.yaml"); Try / catch
try { publish(chart); } catch (ClientException e) { if (e.getMessage().contains("Chart.yaml not found")) fixAndRepackage(chart); } Prevention
- Use 'helm package' exclusively to build chart archives
- Run 'helm lint' before publishing
- Never strip Chart.yaml from archives
When it happens
Trigger: POST/PUT of a .tgz whose entries do not include a root-level Chart.yaml — e.g. the tgz wraps a directory differently, Chart.yaml is missing/renamed, or the archive contains only templates/.
Common situations: Hand-rolled tar files, charts created without 'helm package', archives where Chart.yaml sits under an extra top-level directory after manual zipping, or uploading a Helm-provenance (.prov) or OCI blob by mistake.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Chart name or version not specified
- Error reading chart archive: ${e.getMessage()}
- Title is required
- Count should not be greater than ${RestConstants.MAX_PAGE_SI
- ${e.getMessage()}
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/83648ac6b171473e.
Report an issue: GitHub.