kubernetes/kops · error
unsupported legacy containerd version: %q
Error message
unsupported legacy containerd version: %q
What it means
kOps no longer supports containerd versions older than 2.1.0 for release-asset resolution. findContainerdVersionUrl compares the parsed version against 2.1.0 and rejects anything lower with this error. It exists to steer users off end-of-life containerd releases whose URLs/URL patterns kOps no longer maintains.
Source
Thrown at pkg/nodemodel/wellknownassets/containerd.go:79
}
assetURL, err := findContainerdVersionUrl(arch, version)
if err != nil {
return nil, err
}
canonicalURL = assetURL.String()
}
return buildFileAsset(assetBuilder, canonicalURL, knownHash)
}
func findContainerdVersionUrl(arch architectures.Architecture, version string) (*url.URL, error) {
sv, err := semver.ParseTolerant(version)
if err != nil {
return nil, fmt.Errorf("unable to parse version string: %q", version)
}
if sv.LT(semver.MustParse("2.1.0")) {
return nil, fmt.Errorf("unsupported legacy containerd version: %q", version)
}
var u string
switch arch {
case architectures.ArchitectureAmd64:
u = fmt.Sprintf(containerdReleaseUrlAmd64, version, version)
case architectures.ArchitectureArm64:
u = fmt.Sprintf(containerdReleaseUrlArm64, version, version)
default:
return nil, fmt.Errorf("unknown arch: %q", arch)
}
return url.Parse(u)
}
func buildFileAsset(assetBuilder *assets.AssetBuilder, canonicalURL string, knownHashString string) (*assets.FileAsset, error) {
u, err := url.Parse(canonicalURL)
if err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Upgrade containerd.version in the cluster spec to 2.1.0 or newer
- If an older containerd is mandatory, provide containerd.packages (or equivalent) so a canonicalURL bypasses the version-gate check
- Rebuild the cluster spec from a current kOps template with supported containerd versions
Example fix
// before containerd: version: "1.7.20" // after containerd: version: "2.1.0"
Defensive patterns
Strategy: validation
Validate before calling
sv, err := semver.ParseTolerant(containerdVersion)
if err == nil && sv.LT(semver.MustParse("2.1.0")) {
return fmt.Errorf("containerd %s is unsupported; upgrade to >= 2.1.0", containerdVersion)
} Try / catch
asset, err := wellknownassets.FindContainerdAsset(ig, assetBuilder, arch)
if err != nil && strings.Contains(err.Error(), "unsupported legacy containerd version") {
return fmt.Errorf("please bump containerd.version to >= 2.1.0: %w", err)
} Prevention
- Track kOps release notes for supported containerd minimums before upgrades
- Avoid pinning legacy 1.x containerd in reused cluster templates
- Test cluster spec upgrades in staging with the new containerd version
When it happens
Trigger: FindContainerdAsset falls back to version-based URL resolution with containerd.Version set to e.g. '1.7.20', '1.6.9', or any semver below 2.1.0 (and no Packages override supplying a canonicalURL).
Common situations: Clusters upgraded from older kOps versions that pinned containerd 1.x; copied cluster specs from templates that still use 1.x; users intentionally wanting an older containerd patch release.
Related errors
- unable to find any containerd binaries in assets
- error finding contained version
- error parsing container runtime version %q: %w
- error building containerd flags: %v
- building json: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/bf2ca6868a1f641f.
Report an issue: GitHub.