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

  1. Run 'helm package <chart-dir>' so Chart.yaml is included at the archive root
  2. Confirm 'tar tzf chart.tgz' lists Chart.yaml at the root of the archive
  3. If Chart.yaml is nested under a folder, restructure/repackage so it is at the top level
  4. 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

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


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/83648ac6b171473e. Report an issue: GitHub.