theonedev/onedev · error · ClientException
Error reading chart archive: ${e.getMessage()}
Error message
Error reading chart archive: ${e.getMessage()} What it means
Thrown by HelmPackHandler.handle when an IOException occurs while reading entries of the uploaded .tgz chart archive (opening/reading the tar stream or extracting Chart.yaml). It is a 400 Bad Request telling the client the uploaded archive could not be read, with the underlying IOException message appended.
Source
Thrown at server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java:204
Map<String, Object> metadata = null;
var bytes = baos.toByteArray();
try (var is = new TarInputStream(new GZIPInputStream(new ByteArrayInputStream(bytes)))) {
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);
View on GitHub (pinned to d44925c47c)
Solutions
- Re-package the chart with 'helm package <chart-dir>' and re-upload the resulting .tgz
- Verify the file is a valid gzip tar: 'tar tzf chart.tgz' should list entries including Chart.yaml
- Check network/proxy stability and re-upload; ensure the client sends the full request body
- Check server logs for the wrapped IOException message to identify the exact read failure
Example fix
// before curl -T corrupted-chart.tgz https://server/project/~helm // after helm package mychart curl -T mychart-1.0.0.tgz https://server/project/~helm
Defensive patterns
Strategy: validation
Validate before calling
if (!file.getName().endsWith(".tgz")) throw new IllegalArgumentException("not a chart tgz");
try (var in = new FileInputStream(file)) {
var tar = new TarArchiveInputStream(new GzipCompressorInputStream(in));
TarArchiveEntry e;
boolean hasChartYaml = false;
while ((e = tar.getNextTarEntry()) != null) if (e.getName().equals("Chart.yaml")) { hasChartYaml = true; break; }
if (!hasChartYaml) throw new IllegalArgumentException("Chart.yaml missing at archive root");
} Try / catch
try { handler.upload(chartTgz); } catch (ClientException e) { log.error("chart archive rejected: {}", e.getMessage()); } Prevention
- Always package with 'helm package', never hand-tar the chart
- Verify the tgz with 'tar tzf' before upload
- Use resumable/stable network paths for large uploads
When it happens
Trigger: POST/PUT of a Helm chart package to /~helm where the tar archive is corrupt, truncated, not gzip/tar formatted, or the upload stream fails mid-read so TarArchiveInputStream.getNextEntry/read throws IOException.
Common situations: Uploading a file that is not a real chart tgz (e.g. an HTML error page saved as .tgz), interrupted/partial uploads, proxies corrupting the body, or charts packaged with unusual compression.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Chart archive exceeds maximum size: ${MAX_FILE_SIZE}
- Chart archive not found
- Chart.yaml not found in the archive
- internal error
- Upload must be less than
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/c8d089fe8376e3e7.
Report an issue: GitHub.