goharbor/harbor · error
Failed to read chart.yaml from the chart tgz file. filename
Error message
Failed to read chart.yaml from the chart tgz file. filename {} What it means
Raised by read_chart_version in Harbor's chart v2->OCI migration tool when find_chart_yaml matched a tar member whose name contains "Chart.yaml" but tarfile.extractfile() returned None. extractfile returns None when the matched member is not a regular file (a directory, symlink, fifo, etc.). The exception is caught in ChartV2.__init__, which logs 'Skipped chart ... illegal chart name' and leaves name/version empty so the chart is skipped during the batch migration.
Source
Thrown at tools/migrate_chart/migrate_chart.py:64
return os.path.join(path, member.name)
def read_chart_version(chart_tgz_path):
# Open the chart tgz file
with tarfile.open(chart_tgz_path, 'r:gz') as tar:
# Find the path to chart.yaml within the tarball
chart_yaml_path = find_chart_yaml(tar)
if chart_yaml_path:
# Extract the chart.yaml file
chart_yaml_file = tar.extractfile(chart_yaml_path)
if chart_yaml_file is not None:
# Load the YAML content from chart.yaml
chart_data = yaml.safe_load(chart_yaml_file)
# Read the version from chart.yaml
version = chart_data.get('version')
name = chart_data.get('name')
return name, version
else:
raise Exception("Failed to read chart.yaml from the chart tgz file. filename {}".format(chart_tgz_path))
else:
raise Exception("chart.yaml not found in the chart tgz file. filename {}".format(chart_tgz_path))
class ChartV2:
def __init__(self, filepath:Path):
self.filepath = filepath
self.project = self.filepath.parts[-2]
self.name = ""
self.version = ""
try:
self.name, self.version = read_chart_version(filepath)
if self.name == "" or self.version == "" or self.name is None or self.version is None :
raise Exception('chart name: {} is illegal'.format('-'.join(parts)))
except Exception as e:
click.echo("Skipped chart: {} due to illegal chart name. Error: {}".format(filepath, e), err=True)
return
View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Inspect the archive: tar -tzvf <file>.tgz and check the entry type of anything matching Chart.yaml
- Repackage the chart with helm package, which guarantees a regular-file Chart.yaml at the chart root
- Remove or move the offending tgz out of /chart_storage so the batch run proceeds
- Patch find_chart_yaml to only consider regular files whose basename is exactly Chart.yaml
Example fix
# before
if "Chart.yaml" in member.name:
return os.path.join(path, member.name) # can match dirs/symlinks -> extractfile() returns None
# after
if member.isfile() and os.path.basename(member.name) == "Chart.yaml":
return member.name # regular file only, extractfile() succeeds Defensive patterns
Strategy: validation
Validate before calling
import tarfile
def has_regular_chart_yaml(tgz_path) -> bool:
with tarfile.open(tgz_path, 'r:gz') as tar:
return any(m.isfile() and 'Chart.yaml' in m.name for m in tar.getmembers())
# before migration:
# if not has_regular_chart_yaml(f): quarantine(f) Try / catch
try:
name, version = read_chart_version(filepath)
except Exception as e:
# chart is skipped by design; log and continue the batch
click.echo(f'Skipped chart: {filepath} ({e})', err=True)
continue Prevention
- Always package charts with helm package rather than tar czf
- Pre-scan /chart_storage and remove archives without a regular-file Chart.yaml
- Never store non-chart tgz files in the migration source directory
When it happens
Trigger: A .tgz under /chart_storage/<project>/ contains an entry matching the substring check ("Chart.yaml" in member.name) that is a directory (e.g. a 'Chart.yaml.d' folder), a symlink, or another non-regular file. Because matching is substring-based, unrelated members whose names merely contain 'Chart.yaml' also hit this path.
Common situations: Hand-repacked tgz archives, charts packed with non-Helm tooling, archives with symlinked Chart.yaml, or unusual nested directory layouts inside the tarball.
Related errors
- chart.yaml not found in the chart tgz file. filename {}
- chart name: {} is illegal
- Artifact already exist in harbor
- This operation only allowed for admin
- BAD_REQUEST
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/eefef8a45f2f9cc3.
Report an issue: GitHub.