Virtual helm repo: relative chart URLs not rewritten, causing 404 on .tgz download #33

Closed
opened 2026-05-01 22:07:58 +10:00 by unkinben · 0 comments
Owner

Bug

When Helm fetches a chart from a virtual helm repository, it gets a 404 if the upstream member remote's `index.yaml` uses relative URLs in chart `urls:` fields.

Error seen:
```
Error: failed to fetch https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm/rancher-2.13.1.tgz : 404 Not Found
```

Root Cause

`_merge_helm_indexes` in `virtual.py` rewrites chart URLs via a raw byte `str.replace(base_url, proxy_url)` (delegated to `remote/helm.py`). This only works when the upstream index contains absolute URLs whose prefix matches the configured `base_url`.

Rancher (and other upstreams) use relative URLs (e.g. `urls: [rancher-2.13.1.tgz]`) in their `index.yaml`. The replace finds no match, the URLs remain relative in the merged index, and Helm constructs the absolute URL by appending to the virtual repo base URL — hitting `/api/v1/virtual/helm/rancher-2.13.1.tgz` which returns 404 (virtual repos only serve `index.yaml`).

Fix

Rewrite URLs post-parse rather than via raw byte replacement. After `yaml.safe_load`, iterate each entry's `urls` list:

  • Relative URL → prepend `{proxy_base}/api/v1/remote/{member_name}/`
  • Absolute URL → replace the `base_url` prefix with `{proxy_base}/api/v1/remote/{member_name}`

This handles both cases correctly.

## Bug When Helm fetches a chart from a virtual helm repository, it gets a 404 if the upstream member remote's \`index.yaml\` uses relative URLs in chart \`urls:\` fields. **Error seen:** \`\`\` Error: failed to fetch https://artifactapi.k8s.syd1.au.unkin.net/api/v1/virtual/helm/rancher-2.13.1.tgz : 404 Not Found \`\`\` ## Root Cause \`_merge_helm_indexes\` in \`virtual.py\` rewrites chart URLs via a raw byte \`str.replace(base_url, proxy_url)\` (delegated to \`remote/helm.py\`). This only works when the upstream index contains **absolute URLs** whose prefix matches the configured \`base_url\`. Rancher (and other upstreams) use **relative URLs** (e.g. \`urls: [rancher-2.13.1.tgz]\`) in their \`index.yaml\`. The replace finds no match, the URLs remain relative in the merged index, and Helm constructs the absolute URL by appending to the virtual repo base URL — hitting \`/api/v1/virtual/helm/rancher-2.13.1.tgz\` which returns 404 (virtual repos only serve \`index.yaml\`). ## Fix Rewrite URLs post-parse rather than via raw byte replacement. After \`yaml.safe_load\`, iterate each entry's \`urls\` list: - **Relative URL** → prepend \`{proxy_base}/api/v1/remote/{member_name}/\` - **Absolute URL** → replace the \`base_url\` prefix with \`{proxy_base}/api/v1/remote/{member_name}\` This handles both cases correctly.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/artifactapi#33