What happens
The conventional "latest asset" URL pattern many install/provisioning scripts use:
curl -fsSL "https://github.com/cocoonstack/$repo/releases/latest/download/${repo}_Linux_x86_64.tar.gz" | tar xz
returns 404 for cocoon, cocoon-net, and vk-cocoon. The release assets are version-named (.goreleaser.yml name_template embeds {{ .Version }}), so there is no unversioned asset for releases/latest/download/ to resolve — the 302 to the latest tag lands on a missing asset.
Verified via the GitHub API (2026-07-06):
| Repo |
Latest |
x86_64 asset |
| cocoon |
v0.4.8 |
cocoon_0.4.8_Linux_x86_64.tar.gz (+ arm64, debug, checksums.txt) |
| cocoon-net |
v0.1.8 |
cocoon-net_0.1.8_Linux_x86_64.tar.gz (same pattern) |
| vk-cocoon |
v0.3.2 |
vk-cocoon_0.3.2_Linux_x86_64.tar.gz (same pattern) |
None ships a <repo>_Linux_x86_64.tar.gz without the version.
Why it stays hidden
Provisioning scripts using this URL are typically install-if-missing: on nodes where the binaries already exist, the URL is never re-tested. It only bites on a fresh or wiped node, where the script silently fails to install the cocoon stack ("failed to fetch release") while everything else it installs (cloud-hypervisor, firmware, ...) works fine — i.e. the "self-healing" install path can't actually reinstall cocoon. Discovered exactly this way standing up fresh nodes (2026-07-06).
Reproduce
curl -fsSIL "https://github.com/cocoonstack/cocoon/releases/latest/download/cocoon_Linux_x86_64.tar.gz"
# 302 to the v0.4.8 tag, then 404 — asset does not exist
Workaround (used successfully on fresh nodes)
Resolve the real versioned asset via the API:
url="$(curl -fsSL "https://api.github.com/repos/cocoonstack/$repo/releases/latest" \
| grep -o "https://[^\"]*_Linux_x86_64\.tar\.gz" | grep -v debug | head -1)"
curl -fsSL "$url" | tar xz
Suggested fixes
- Preferred — fixes every consumer at once: have the release pipeline also publish a stable unversioned asset name (or a
latest-alias asset) alongside the versioned archive, e.g. upload a copy as cocoon_Linux_x86_64.tar.gz. Then the conventional releases/latest/download/ URL works forever.
- Alternatively, patch install/provisioning scripts to resolve the asset via the API (snippet above).
Filing here since cocoon owns the node tooling and is the first repo the pattern breaks on, but the same applies to cocoon-net and vk-cocoon releases (identical goreleaser naming).
What happens
The conventional "latest asset" URL pattern many install/provisioning scripts use:
returns 404 for
cocoon,cocoon-net, andvk-cocoon. The release assets are version-named (.goreleaser.ymlname_templateembeds{{ .Version }}), so there is no unversioned asset forreleases/latest/download/to resolve — the 302 to the latest tag lands on a missing asset.Verified via the GitHub API (2026-07-06):
cocoon_0.4.8_Linux_x86_64.tar.gz(+ arm64, debug, checksums.txt)cocoon-net_0.1.8_Linux_x86_64.tar.gz(same pattern)vk-cocoon_0.3.2_Linux_x86_64.tar.gz(same pattern)None ships a
<repo>_Linux_x86_64.tar.gzwithout the version.Why it stays hidden
Provisioning scripts using this URL are typically install-if-missing: on nodes where the binaries already exist, the URL is never re-tested. It only bites on a fresh or wiped node, where the script silently fails to install the cocoon stack ("failed to fetch release") while everything else it installs (cloud-hypervisor, firmware, ...) works fine — i.e. the "self-healing" install path can't actually reinstall cocoon. Discovered exactly this way standing up fresh nodes (2026-07-06).
Reproduce
Workaround (used successfully on fresh nodes)
Resolve the real versioned asset via the API:
Suggested fixes
latest-alias asset) alongside the versioned archive, e.g. upload a copy ascocoon_Linux_x86_64.tar.gz. Then the conventionalreleases/latest/download/URL works forever.Filing here since cocoon owns the node tooling and is the first repo the pattern breaks on, but the same applies to
cocoon-netandvk-cocoonreleases (identical goreleaser naming).